diff options
author | David Faure <david.faure@kdab.com> | 2012-10-23 22:25:10 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-11-23 15:18:55 +0100 |
commit | 7120cf16d21923ecbae37c17c071eca2e7f891ab (patch) | |
tree | c950e07cce1e2394996b1590efbb07311a63d087 | |
parent | 27aa41cbba6c0bd76148fde63863cfbba0ec2456 (diff) |
Fix race condition on d->state, by locking the mutex first.
Detected by helgrind ./tst_qurl testThreads
Change-Id: I0fe01153cd119741ce8a2bfe7dddead7c6ebf0b0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
-rw-r--r-- | src/corelib/thread/qfutureinterface.cpp | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index bad55811fe..a293c711cd 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); |