diff options
author | David Faure <david.faure@kdab.com> | 2016-02-06 14:06:29 +0100 |
---|---|---|
committer | David Faure <david.faure@kdab.com> | 2016-02-15 13:53:57 +0000 |
commit | 78b8f7803bb662e3e73daa796d61baae84cd6ea9 (patch) | |
tree | 3e962411e9c05a796965ea6f2324771e00990a49 | |
parent | bbc830ce3e9933767924452d416923a4fa6fa5da (diff) |
QtConcurrentRun: add unittest for polling for isFinished()
I had intermittent failures with this kind of code in my unittests,
not sure why yet. This test seems to pass reliably, apart from
helgrind saying it triggers the known race in QFuture::isFinished,
for which Marc is working on a fix.
Change-Id: I4aabe77566dc1af859a016ffe8a4cce19ddf25c8
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
-rw-r--r-- | tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp index d9ea8ef71b..1b0ac7a8bc 100644 --- a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp +++ b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp @@ -43,6 +43,7 @@ private slots: void memberFunctions(); void implicitConvertibleTypes(); void runWaitLoop(); + void pollForIsFinished(); void recursive(); #ifndef QT_NO_EXCEPTIONS void exceptions(); @@ -348,6 +349,34 @@ void tst_QtConcurrentRun::runWaitLoop() run(fn).waitForFinished(); } +static bool allFinished(const QList<QFuture<void> > &futures) +{ + auto hasNotFinished = [](const QFuture<void> &future) { return !future.isFinished(); }; + return std::find_if(futures.cbegin(), futures.cend(), hasNotFinished) + == futures.constEnd(); +} + +static void runFunction() +{ + QEventLoop loop; + QTimer::singleShot(20, &loop, &QEventLoop::quit); + loop.exec(); +} + +void tst_QtConcurrentRun::pollForIsFinished() +{ + const int numThreads = std::max(4, 2 * QThread::idealThreadCount()); + QThreadPool::globalInstance()->setMaxThreadCount(numThreads); + + QFutureSynchronizer<void> synchronizer; + for (int i = 0; i < numThreads; ++i) + synchronizer.addFuture(QtConcurrent::run(&runFunction)); + + // same as synchronizer.waitForFinished() but with a timeout + QTRY_VERIFY(allFinished(synchronizer.futures())); +} + + QAtomicInt count; void recursiveRun(int level) |