summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-11-23 12:32:56 +0100
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2017-11-23 12:52:18 +0100
commit7c4b0aa9706bdb79f0f79841cf6704e2f613fe69 (patch)
tree77acbaa2d335759e0a5ed04d37608dce2b12acbc /tests/auto/corelib
parent110e49c9cecca34dfacad33d19e04612cc2671b2 (diff)
parenteade2255ea7cd8200569080e9b295479b1f51bed (diff)
Merge remote-tracking branch 'origin/5.9' into 5.10
Conflicts: src/corelib/io/qstandardpaths_win.cpp src/plugins/platforms/ios/qioswindow.mm src/plugins/platforms/ios/quiview.mm tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp Change-Id: I5deb0a0176a454a9c566e924d074ba60ce04f0bc
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r--tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp68
1 files changed, 68 insertions, 0 deletions
diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
index 094c6ed0a5..1092216fb7 100644
--- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
+++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
@@ -95,6 +95,7 @@ private slots:
void stackSize();
void stressTest();
void takeAllAndIncreaseMaxThreadCount();
+ void waitForDoneAfterTake();
private:
QMutex m_functionTestMutex;
@@ -1267,5 +1268,72 @@ void tst_QThreadPool::takeAllAndIncreaseMaxThreadCount() {
delete task3;
}
+void tst_QThreadPool::waitForDoneAfterTake()
+{
+ class Task : public QRunnable
+ {
+ public:
+ Task(QSemaphore *mainBarrier, QSemaphore *threadBarrier)
+ : m_mainBarrier(mainBarrier)
+ , m_threadBarrier(threadBarrier)
+ {}
+
+ void run()
+ {
+ m_mainBarrier->release();
+ m_threadBarrier->acquire();
+ }
+
+ private:
+ QSemaphore *m_mainBarrier = nullptr;
+ QSemaphore *m_threadBarrier = nullptr;
+ };
+
+ int threadCount = 4;
+
+ // Blocks the main thread from releasing the threadBarrier before all run() functions have started
+ QSemaphore mainBarrier;
+ // Blocks the tasks from completing their run function
+ QSemaphore threadBarrier;
+
+ QThreadPool manager;
+ manager.setMaxThreadCount(threadCount);
+
+ // Fill all the threads with runnables that wait for the threadBarrier
+ for (int i = 0; i < threadCount; i++) {
+ auto *task = new Task(&mainBarrier, &threadBarrier);
+ manager.start(task);
+ }
+
+ QVERIFY(manager.activeThreadCount() == manager.maxThreadCount());
+
+ // Add runnables that are immediately removed from the pool queue.
+ // This sets the queue elements to nullptr in QThreadPool and we want to test that
+ // the threads keep going through the queue after encountering a nullptr.
+ for (int i = 0; i < threadCount; i++) {
+ QRunnable *runnable = createTask(emptyFunct);
+ manager.start(runnable);
+ QVERIFY(manager.tryTake(runnable));
+ }
+
+ // Add another runnable that will not be removed
+ manager.start(createTask(emptyFunct));
+
+ // Wait for the first runnables to start
+ mainBarrier.acquire(threadCount);
+
+ QVERIFY(mainBarrier.available() == 0);
+ QVERIFY(threadBarrier.available() == 0);
+
+ // Release runnables that are waiting and expect all runnables to complete
+ threadBarrier.release(threadCount);
+
+ // Using qFatal instead of QVERIFY to force exit if threads are still running after timeout.
+ // Otherwise, QCoreApplication will still wait for the stale threads and never exit the test.
+ if (!manager.waitForDone(5 * 60 * 1000))
+ qFatal("waitForDone returned false. Aborting to stop background threads.");
+
+}
+
QTEST_MAIN(tst_QThreadPool);
#include "tst_qthreadpool.moc"