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>
This commit is contained in:
David Faure 2016-02-06 14:06:29 +01:00
parent bbc830ce3e
commit 78b8f7803b

View File

@ -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)