summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Faure <david.faure@kdab.com>2016-02-06 14:06:29 +0100
committerDavid Faure <david.faure@kdab.com>2016-02-15 13:53:57 +0000
commit78b8f7803bb662e3e73daa796d61baae84cd6ea9 (patch)
tree3e962411e9c05a796965ea6f2324771e00990a49
parentbbc830ce3e9933767924452d416923a4fa6fa5da (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.cpp29
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)