From 78b8f7803bb662e3e73daa796d61baae84cd6ea9 Mon Sep 17 00:00:00 2001 From: David Faure Date: Sat, 6 Feb 2016 14:06:29 +0100 Subject: [PATCH] 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 --- .../qtconcurrentrun/tst_qtconcurrentrun.cpp | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp index d9ea8ef71b5..1b0ac7a8bcf 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 > &futures) +{ + auto hasNotFinished = [](const QFuture &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 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)