summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/thread/qthreadpool.cpp37
-rw-r--r--src/corelib/thread/qthreadpool.h9
-rw-r--r--src/corelib/thread/qthreadpool_p.h13
-rw-r--r--tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp92
4 files changed, 120 insertions, 31 deletions
diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp
index 6d258af9df..b1f538fa43 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,10 +223,8 @@ void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority)
int QThreadPoolPrivate::activeThreadCount() const
{
- return (allThreads.count()
- - expiredThreads.count()
- - waitingThreads.count()
- + reservedThreads);
+ return int(allThreads.count() - expiredThreads.count() - waitingThreads.count()
+ + reservedThreads);
}
void QThreadPoolPrivate::tryToStartMoreThreads()
@@ -605,11 +603,15 @@ int QThreadPool::expiryTimeout() const
void QThreadPool::setExpiryTimeout(int expiryTimeout)
{
Q_D(QThreadPool);
- if (d->expiryTimeout == expiryTimeout)
- return;
d->expiryTimeout = expiryTimeout;
}
+QBindable<int> QThreadPool::bindableExpiryTimeout()
+{
+ Q_D(QThreadPool);
+ return &d->expiryTimeout;
+}
+
/*! \property QThreadPool::maxThreadCount
\brief the maximum number of threads used by the thread pool.
@@ -631,11 +633,18 @@ void QThreadPool::setMaxThreadCount(int maxThreadCount)
Q_D(QThreadPool);
QMutexLocker locker(&d->mutex);
- if (maxThreadCount == d->maxThreadCount)
- return;
-
+ const auto maxThreadCountChanged = maxThreadCount != d->maxThreadCount;
+ // Rewrite the value in any case, to make sure the binding is cleared.
d->maxThreadCount = maxThreadCount;
- d->tryToStartMoreThreads();
+
+ if (maxThreadCountChanged)
+ d->tryToStartMoreThreads();
+}
+
+QBindable<int> QThreadPool::bindableMaxThreadCount()
+{
+ Q_D(QThreadPool);
+ return &d->maxThreadCount;
}
/*! \property QThreadPool::activeThreadCount
@@ -698,6 +707,12 @@ uint QThreadPool::stackSize() const
return d->stackSize;
}
+QBindable<uint> 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 a559eff49a..3e601dd963 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)
- Q_PROPERTY(int maxThreadCount READ maxThreadCount WRITE setMaxThreadCount)
+ Q_PROPERTY(int expiryTimeout READ expiryTimeout WRITE setExpiryTimeout BINDABLE bindableExpiryTimeout)
+ Q_PROPERTY(int maxThreadCount READ maxThreadCount WRITE setMaxThreadCount BINDABLE bindableMaxThreadCount)
Q_PROPERTY(int activeThreadCount READ activeThreadCount)
- Q_PROPERTY(uint stackSize READ stackSize WRITE setStackSize)
+ Q_PROPERTY(uint stackSize READ stackSize WRITE setStackSize BINDABLE bindableStackSize)
friend class QFutureInterfaceBase;
public:
@@ -76,14 +76,17 @@ public:
int expiryTimeout() const;
void setExpiryTimeout(int expiryTimeout);
+ QBindable<int> bindableExpiryTimeout();
int maxThreadCount() const;
void setMaxThreadCount(int maxThreadCount);
+ QBindable<int> bindableMaxThreadCount();
int activeThreadCount() const;
void setStackSize(uint stackSize);
uint stackSize() const;
+ QBindable<uint> bindableStackSize();
void reserveThread();
void releaseThread();
diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h
index 4d73a480b5..019f24ce4d 100644
--- a/src/corelib/thread/qthreadpool_p.h
+++ b/src/corelib/thread/qthreadpool_p.h
@@ -58,6 +58,7 @@
#include "QtCore/qset.h"
#include "QtCore/qqueue.h"
#include "private/qobject_p.h"
+#include "private/qproperty_p.h"
QT_REQUIRE_CONFIG(thread);
@@ -173,11 +174,17 @@ public:
QList<QueuePage *> queue;
QWaitCondition noActiveThreads;
- int expiryTimeout = 30000;
- int maxThreadCount = QThread::idealThreadCount();
+ 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 reservedThreads = 0;
int activeThreads = 0;
- uint stackSize = 0;
+
+ Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QThreadPoolPrivate, 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 5960ac20a3..00c8a84ca7 100644
--- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
+++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
@@ -104,8 +104,23 @@ 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;
};
@@ -471,20 +486,6 @@ 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);
@@ -1305,5 +1306,68 @@ void tst_QThreadPool::waitForDoneAfterTake()
}
+void tst_QThreadPool::bindings()
+{
+ {
+ QThreadPool pool;
+
+ // expiryTimeout property
+ QProperty<int> expiryTimeout;
+ pool.bindableExpiryTimeout().setBinding(Qt::makePropertyBinding(expiryTimeout));
+ expiryTimeout = 1000;
+ QCOMPARE(pool.expiryTimeout(), 1000);
+
+ QProperty<int> expiryTimeoutObserver;
+ expiryTimeoutObserver.setBinding(pool.bindableExpiryTimeout().makeBinding());
+ pool.setExpiryTimeout(100);
+ QCOMPARE(expiryTimeoutObserver, 100);
+
+ // stackSize property
+ QProperty<uint> stackSize;
+ pool.bindableStackSize().setBinding(Qt::makePropertyBinding(stackSize));
+ stackSize = 1000;
+ QCOMPARE(pool.stackSize(), 1000);
+
+ QProperty<uint> 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<int> 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<int> maxThreadCountObserver;
+ maxThreadCountObserver.setBinding(pool.bindableMaxThreadCount().makeBinding());
+ pool.setMaxThreadCount(10);
+ QCOMPARE(maxThreadCountObserver, 10);
+ }
+}
+
QTEST_MAIN(tst_QThreadPool);
#include "tst_qthreadpool.moc"