From f2c3b52c6c513ebba9dc0db69efe8bdbf6be8334 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 28 Jan 2021 12:36:59 +0000 Subject: [PATCH] Revert "Port QThreadPool to the new property system" This reverts commit 8f8405e04642b98663d4752d4ae76c304ae33b01. Reason for revert: Appears not entirely thread-safe and caused QTBUG-90705 Change-Id: I390c0b1a555a18e6a095b52010371d017071e26b Fixes: QTBUG-90705 Reviewed-by: Sona Kurazyan --- src/corelib/thread/qthreadpool.cpp | 37 +++----- src/corelib/thread/qthreadpool.h | 9 +- src/corelib/thread/qthreadpool_p.h | 13 +-- .../thread/qthreadpool/tst_qthreadpool.cpp | 92 +++---------------- 4 files changed, 31 insertions(+), 120 deletions(-) diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index b1f538fa431..6d258af9df0 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -163,7 +163,7 @@ void QThreadPoolThread::registerThreadInactive() /* \internal */ -QThreadPoolPrivate::QThreadPoolPrivate() +QThreadPoolPrivate:: QThreadPoolPrivate() { } bool QThreadPoolPrivate::tryStart(QRunnable *task) @@ -223,8 +223,10 @@ void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority) int QThreadPoolPrivate::activeThreadCount() const { - return int(allThreads.count() - expiredThreads.count() - waitingThreads.count() - + reservedThreads); + return (allThreads.count() + - expiredThreads.count() + - waitingThreads.count() + + reservedThreads); } void QThreadPoolPrivate::tryToStartMoreThreads() @@ -603,15 +605,11 @@ int QThreadPool::expiryTimeout() const void QThreadPool::setExpiryTimeout(int expiryTimeout) { Q_D(QThreadPool); + if (d->expiryTimeout == expiryTimeout) + return; d->expiryTimeout = expiryTimeout; } -QBindable QThreadPool::bindableExpiryTimeout() -{ - Q_D(QThreadPool); - return &d->expiryTimeout; -} - /*! \property QThreadPool::maxThreadCount \brief the maximum number of threads used by the thread pool. @@ -633,18 +631,11 @@ void QThreadPool::setMaxThreadCount(int maxThreadCount) Q_D(QThreadPool); QMutexLocker locker(&d->mutex); - const auto maxThreadCountChanged = maxThreadCount != d->maxThreadCount; - // Rewrite the value in any case, to make sure the binding is cleared. + if (maxThreadCount == d->maxThreadCount) + return; + d->maxThreadCount = maxThreadCount; - - if (maxThreadCountChanged) - d->tryToStartMoreThreads(); -} - -QBindable QThreadPool::bindableMaxThreadCount() -{ - Q_D(QThreadPool); - return &d->maxThreadCount; + d->tryToStartMoreThreads(); } /*! \property QThreadPool::activeThreadCount @@ -707,12 +698,6 @@ uint QThreadPool::stackSize() const return d->stackSize; } -QBindable QThreadPool::bindableStackSize() -{ - Q_D(QThreadPool); - return &d->stackSize; -} - /*! Releases a thread previously reserved by a call to reserveThread(). diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h index 3e601dd9637..a559eff49aa 100644 --- a/src/corelib/thread/qthreadpool.h +++ b/src/corelib/thread/qthreadpool.h @@ -56,10 +56,10 @@ class Q_CORE_EXPORT QThreadPool : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QThreadPool) - Q_PROPERTY(int expiryTimeout READ expiryTimeout WRITE setExpiryTimeout BINDABLE bindableExpiryTimeout) - Q_PROPERTY(int maxThreadCount READ maxThreadCount WRITE setMaxThreadCount BINDABLE bindableMaxThreadCount) + Q_PROPERTY(int expiryTimeout READ expiryTimeout WRITE setExpiryTimeout) + Q_PROPERTY(int maxThreadCount READ maxThreadCount WRITE setMaxThreadCount) Q_PROPERTY(int activeThreadCount READ activeThreadCount) - Q_PROPERTY(uint stackSize READ stackSize WRITE setStackSize BINDABLE bindableStackSize) + Q_PROPERTY(uint stackSize READ stackSize WRITE setStackSize) friend class QFutureInterfaceBase; public: @@ -76,17 +76,14 @@ public: int expiryTimeout() const; void setExpiryTimeout(int expiryTimeout); - QBindable bindableExpiryTimeout(); int maxThreadCount() const; void setMaxThreadCount(int maxThreadCount); - QBindable bindableMaxThreadCount(); int activeThreadCount() const; void setStackSize(uint stackSize); uint stackSize() const; - QBindable bindableStackSize(); void reserveThread(); void releaseThread(); diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h index 019f24ce4d9..4d73a480b51 100644 --- a/src/corelib/thread/qthreadpool_p.h +++ b/src/corelib/thread/qthreadpool_p.h @@ -58,7 +58,6 @@ #include "QtCore/qset.h" #include "QtCore/qqueue.h" #include "private/qobject_p.h" -#include "private/qproperty_p.h" QT_REQUIRE_CONFIG(thread); @@ -174,17 +173,11 @@ public: QList queue; QWaitCondition noActiveThreads; - Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QThreadPoolPrivate, int, expiryTimeout, 30000) - - void setMaxThreadCount(int count) { q_func()->setMaxThreadCount(count); } - Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QThreadPoolPrivate, int, maxThreadCount, - &QThreadPoolPrivate::setMaxThreadCount, - QThread::idealThreadCount()) - + int expiryTimeout = 30000; + int maxThreadCount = QThread::idealThreadCount(); int reservedThreads = 0; int activeThreads = 0; - - Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QThreadPoolPrivate, uint, stackSize, 0) + uint stackSize = 0; }; QT_END_NAMESPACE diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 00c8a84ca78..5960ac20a30 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -104,23 +104,8 @@ private slots: void stressTest(); void takeAllAndIncreaseMaxThreadCount(); void waitForDoneAfterTake(); - void bindings(); private: - class WaitingTask : public QRunnable - { - public: - QSemaphore waitForStarted, waitToFinish; - - WaitingTask() { setAutoDelete(false); } - - void run() override - { - waitForStarted.release(); - waitToFinish.acquire(); - } - }; - QMutex m_functionTestMutex; }; @@ -486,6 +471,20 @@ void tst_QThreadPool::setMaxThreadCount() void tst_QThreadPool::setMaxThreadCountStartsAndStopsThreads() { + class WaitingTask : public QRunnable + { + public: + QSemaphore waitForStarted, waitToFinish; + + WaitingTask() { setAutoDelete(false); } + + void run() override + { + waitForStarted.release(); + waitToFinish.acquire(); + } + }; + QThreadPool threadPool; threadPool.setMaxThreadCount(1); @@ -1306,68 +1305,5 @@ void tst_QThreadPool::waitForDoneAfterTake() } -void tst_QThreadPool::bindings() -{ - { - QThreadPool pool; - - // expiryTimeout property - QProperty expiryTimeout; - pool.bindableExpiryTimeout().setBinding(Qt::makePropertyBinding(expiryTimeout)); - expiryTimeout = 1000; - QCOMPARE(pool.expiryTimeout(), 1000); - - QProperty expiryTimeoutObserver; - expiryTimeoutObserver.setBinding(pool.bindableExpiryTimeout().makeBinding()); - pool.setExpiryTimeout(100); - QCOMPARE(expiryTimeoutObserver, 100); - - // stackSize property - QProperty stackSize; - pool.bindableStackSize().setBinding(Qt::makePropertyBinding(stackSize)); - stackSize = 1000; - QCOMPARE(pool.stackSize(), 1000); - - QProperty stackSizeObserver; - stackSizeObserver.setBinding(pool.bindableStackSize().makeBinding()); - pool.setStackSize(100); - QCOMPARE(stackSizeObserver, 100); - } - - // maxThreadCount property - { - // Make sure changing the max thread count via binding starts new threads - QThreadPool pool; - WaitingTask task; - - pool.setMaxThreadCount(1); - pool.start(&task); - pool.start(&task); - QVERIFY(task.waitForStarted.tryAcquire(1, 1000)); - - // thread limit is 1, cannot start more tasks - QVERIFY(!task.waitForStarted.tryAcquire(1, 1000)); - QCOMPARE(pool.activeThreadCount(), 1); - - QProperty maxThreadCount; - pool.bindableMaxThreadCount().setBinding(Qt::makePropertyBinding(maxThreadCount)); - - maxThreadCount = 2; - QCOMPARE(pool.maxThreadCount(), 2); - - // increasing thread count should allow starting more tasks - QVERIFY(task.waitForStarted.tryAcquire(1, 1000)); - QCOMPARE(pool.activeThreadCount(), 2); - - task.waitToFinish.release(2); - pool.waitForDone(); - - QProperty maxThreadCountObserver; - maxThreadCountObserver.setBinding(pool.bindableMaxThreadCount().makeBinding()); - pool.setMaxThreadCount(10); - QCOMPARE(maxThreadCountObserver, 10); - } -} - QTEST_MAIN(tst_QThreadPool); #include "tst_qthreadpool.moc"