summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/thread
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-04-22 14:33:17 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-10-01 12:01:21 +0200
commit9a6c653eaf22f604289a02c844af3bc5880605e1 (patch)
tree137eef7af8da14ad3f62a3580668756a543b8457 /tests/auto/corelib/thread
parent2fea6bbe8e822b3fb59a7f74c0165e7a8aeb727a (diff)
Cleanup of qthreadpool
Don't bother overwaiting in waitForDone(), if it was done at one point after it was called we can return true. And do not stop threads recently awakened by a startThread call as they have tasks to do. Make allowing at least one thread regardless of reservation more standard instead of hacked in certain places. Pick-to: 6.2 Change-Id: I304bcdc5822f440d5e72fc33ba2aa1678c9ba0d0 Reviewed-by: David Faure <david.faure@kdab.com>
Diffstat (limited to 'tests/auto/corelib/thread')
-rw-r--r--tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp63
1 files changed, 56 insertions, 7 deletions
diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
index 7f36db03e1..3ce4ee09b3 100644
--- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
+++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
@@ -89,6 +89,7 @@ private slots:
void releaseThread_data();
void releaseThread();
void reserveAndStart();
+ void releaseAndBlock();
void start();
void tryStart();
void tryStartPeakThreadCount();
@@ -713,21 +714,19 @@ void tst_QThreadPool::reserveAndStart() // QTBUG-21051
threadpool->reserveThread();
QCOMPARE(threadpool->activeThreadCount(), 1);
- // start a task, to get a running thread
+ // start a task, to get a running thread, works since one thread is always allowed
WaitingTask task;
threadpool->start(&task);
QCOMPARE(threadpool->activeThreadCount(), 2);
+ // tryStart() will fail since activeThreadCount() >= maxThreadCount() and one thread is already running
+ QVERIFY(!threadpool->tryStart(&task));
+ QTRY_COMPARE(threadpool->activeThreadCount(), 2);
task.waitForStarted.acquire();
task.waitBeforeDone.release();
QTRY_COMPARE(task.count.loadRelaxed(), 1);
QTRY_COMPARE(threadpool->activeThreadCount(), 1);
- // now the thread is waiting, but tryStart() will fail since activeThreadCount() >= maxThreadCount()
- QVERIFY(!threadpool->tryStart(&task));
- QTRY_COMPARE(threadpool->activeThreadCount(), 1);
-
- // start() will therefore do a failing tryStart(), followed by enqueueTask()
- // which will actually wake up the waiting thread.
+ // start() will wake up the waiting thread.
threadpool->start(&task);
QTRY_COMPARE(threadpool->activeThreadCount(), 2);
task.waitForStarted.acquire();
@@ -741,6 +740,54 @@ void tst_QThreadPool::reserveAndStart() // QTBUG-21051
threadpool->setMaxThreadCount(savedLimit);
}
+void tst_QThreadPool::releaseAndBlock()
+{
+ class WaitingTask : public QRunnable
+ {
+ public:
+ QSemaphore waitBeforeDone;
+
+ WaitingTask() { setAutoDelete(false); }
+
+ void run() override
+ {
+ waitBeforeDone.acquire();
+ }
+ };
+
+ // Set up
+ QThreadPool *threadpool = QThreadPool::globalInstance();
+ const int savedLimit = threadpool->maxThreadCount();
+ threadpool->setMaxThreadCount(1);
+ QCOMPARE(threadpool->activeThreadCount(), 0);
+
+ // start a task, to get a running thread, works since one thread is always allowed
+ WaitingTask task1, task2;
+ threadpool->start(&task1);
+ QCOMPARE(threadpool->activeThreadCount(), 1);
+
+ // tryStart() will fail since activeThreadCount() >= maxThreadCount() and one thread is already running
+ QVERIFY(!threadpool->tryStart(&task2));
+ QCOMPARE(threadpool->activeThreadCount(), 1);
+
+ // Use release without reserve to account for the blocking thread.
+ threadpool->releaseThread();
+ QTRY_COMPARE(threadpool->activeThreadCount(), 0);
+
+ // Now we can start task2
+ QVERIFY(threadpool->tryStart(&task2));
+ QCOMPARE(threadpool->activeThreadCount(), 1);
+ task2.waitBeforeDone.release();
+ QTRY_COMPARE(threadpool->activeThreadCount(), 0);
+
+ threadpool->reserveThread();
+ QCOMPARE(threadpool->activeThreadCount(), 1);
+ task1.waitBeforeDone.release();
+ QTRY_COMPARE(threadpool->activeThreadCount(), 0);
+
+ threadpool->setMaxThreadCount(savedLimit);
+}
+
static QAtomicInt count;
class CountingRunnable : public QRunnable
{
@@ -917,6 +964,7 @@ void tst_QThreadPool::waitForDone()
{
QElapsedTimer total, pass;
total.start();
+ pass.start();
QThreadPool threadPool;
while (total.elapsed() < 10000) {
@@ -1101,6 +1149,7 @@ void tst_QThreadPool::destroyingWaitsForTasksToFinish()
{
QElapsedTimer total, pass;
total.start();
+ pass.start();
while (total.elapsed() < 10000) {
int runs;