summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-01 09:56:16 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-01 20:55:04 +0200
commita5e6c50ef45e9b75867e1730c510f5739b00f176 (patch)
treea4ae5121eebbffbe24c7be1316e90dc51aa3f31b /tests
parentc9d2d93d0f800e0097e6b35d32a3bb251cf9070d (diff)
Fix race condition in QThreadPool::clear
Since we drop the lock while deleting threads, we need to handle the queue possibly being accessed and changed by the pool threads while clear() is running. Fixes: QTBUG-87092 Change-Id: I7611edab90520454278502a58621e299f9cd1f6e Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io> (cherry picked from commit fe36d47b371b71ad5fec30d4b5d7bf0baa0205ea) Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
index 49ce918caf..cd245030db 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();
#if QT_DEPRECATED_SINCE(5, 9)
void cancel();
#endif
@@ -976,6 +977,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());
+}
+
#if QT_DEPRECATED_SINCE(5, 9)
void tst_QThreadPool::cancel()
{