From 7120cf16d21923ecbae37c17c071eca2e7f891ab Mon Sep 17 00:00:00 2001 From: David Faure Date: Tue, 23 Oct 2012 22:25:10 +0200 Subject: [PATCH] Fix race condition on d->state, by locking the mutex first. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Detected by helgrind ./tst_qurl testThreads Change-Id: I0fe01153cd119741ce8a2bfe7dddead7c6ebf0b0 Reviewed-by: Thiago Macieira Reviewed-by: Morten Johan Sørvig --- src/corelib/thread/qfutureinterface.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index bad55811fe7..a293c711cd1 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -283,14 +283,16 @@ void QFutureInterfaceBase::waitForResult(int resultIndex) { d->m_exceptionStore.throwPossibleException(); + QMutexLocker lock(&d->m_mutex); if (!(d->state & Running)) return; + lock.unlock(); // To avoid deadlocks and reduce the number of threads used, try to // run the runnable in the current thread. QThreadPool::globalInstance()->d_func()->stealRunnable(d->runnable); - QMutexLocker lock(&d->m_mutex); + lock.relock(); if (!(d->state & Running)) return; @@ -304,10 +306,14 @@ void QFutureInterfaceBase::waitForResult(int resultIndex) void QFutureInterfaceBase::waitForFinished() { - if (d->state & Running) { + QMutexLocker lock(&d->m_mutex); + const bool alreadyFinished = !(d->state & Running); + lock.unlock(); + + if (!alreadyFinished) { QThreadPool::globalInstance()->d_func()->stealRunnable(d->runnable); - QMutexLocker lock(&d->m_mutex); + lock.relock(); while (d->state & Running) d->waitCondition.wait(&d->m_mutex);