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>
This commit is contained in:
David Faure 2012-10-23 22:25:10 +02:00 committed by The Qt Project
parent 27aa41cbba
commit 7120cf16d2

View File

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