diff options
-rw-r--r-- | src/corelib/thread/qthreadpool.cpp | 6 | ||||
-rw-r--r-- | tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp | 26 |
2 files changed, 29 insertions, 3 deletions
diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index 1b417aa8be..5765bf6b09 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -325,7 +325,8 @@ bool QThreadPoolPrivate::waitForDone(int msecs) void QThreadPoolPrivate::clear() { QMutexLocker locker(&mutex); - for (QueuePage *page : qAsConst(queue)) { + while (!queue.isEmpty()) { + auto *page = queue.takeLast(); while (!page->isFinished()) { QRunnable *r = page->pop(); if (r && r->autoDelete()) { @@ -335,9 +336,8 @@ void QThreadPoolPrivate::clear() locker.relock(); } } + delete page; } - qDeleteAll(queue); - queue.clear(); } /*! diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 9b536aec00..3054e3c5a4 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -93,6 +93,7 @@ private slots: void priorityStart(); void waitForDone(); void clear(); + void clearWithAutoDelete(); void tryTake(); void waitForDoneTimeout(); void destroyingWaitsForTasksToFinish(); @@ -974,6 +975,31 @@ void tst_QThreadPool::clear() QCOMPARE(count.loadRelaxed(), threadPool.maxThreadCount()); } +void tst_QThreadPool::clearWithAutoDelete() +{ + class MyRunnable : public QRunnable + { + public: + MyRunnable() {} + void run() override { QThread::usleep(30); } + }; + + QThreadPool threadPool; + threadPool.setMaxThreadCount(4); + const int loopCount = 20; + const int batchSize = 500; + // Should not crash see QTBUG-87092 + for (int i = 0; i < loopCount; i++) { + threadPool.clear(); + for (int j = 0; j < batchSize; j++) { + auto *runnable = new MyRunnable(); + runnable->setAutoDelete(true); + threadPool.start(runnable); + } + } + QVERIFY(threadPool.waitForDone()); +} + void tst_QThreadPool::tryTake() { QSemaphore sem(0); |