From 5a5a09289fdc326be2e185e4d63dc243ce466e6c Mon Sep 17 00:00:00 2001 From: David Faure Date: Fri, 15 Mar 2013 19:38:21 +0100 Subject: QEventLoop: fix race on 'exit' and 'returnCode' private members Change-Id: I380046f386448783e3e4e93bde8cbe15b9b0279e Reviewed-by: Thiago Macieira --- src/corelib/kernel/qeventloop.cpp | 12 ++++++------ src/corelib/kernel/qeventloop_p.h | 12 ++++++++---- 2 files changed, 14 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index 549b8db9ca..3cb6890821 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -180,7 +180,7 @@ int QEventLoop::exec(ProcessEventsFlags flags) LoopReference(QEventLoopPrivate *d, QMutexLocker &locker) : d(d), locker(locker), exceptionCaught(true) { d->inExec = true; - d->exit = false; + d->exit.storeRelease(false); ++d->threadData->loopLevel; d->threadData->eventLoops.push(d->q_func()); locker.unlock(); @@ -208,11 +208,11 @@ int QEventLoop::exec(ProcessEventsFlags flags) if (app && app->thread() == thread()) QCoreApplication::removePostedEvents(app, QEvent::Quit); - while (!d->exit) + while (!d->exit.loadAcquire()) processEvents(flags | WaitForMoreEvents | EventLoopExec); ref.exceptionCaught = false; - return d->returnCode; + return d->returnCode.load(); } /*! @@ -266,8 +266,8 @@ void QEventLoop::exit(int returnCode) if (!d->threadData->eventDispatcher.load()) return; - d->returnCode = returnCode; - d->exit = true; + d->returnCode.store(returnCode); + d->exit.storeRelease(true); d->threadData->eventDispatcher.load()->interrupt(); } @@ -281,7 +281,7 @@ void QEventLoop::exit(int returnCode) bool QEventLoop::isRunning() const { Q_D(const QEventLoop); - return !d->exit; + return !d->exit.loadAcquire(); } /*! diff --git a/src/corelib/kernel/qeventloop_p.h b/src/corelib/kernel/qeventloop_p.h index 8e2bfdb55e..30c61ca759 100644 --- a/src/corelib/kernel/qeventloop_p.h +++ b/src/corelib/kernel/qeventloop_p.h @@ -51,13 +51,17 @@ class QEventLoopPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QEventLoop) public: inline QEventLoopPrivate() - : exit(true), inExec(false), returnCode(-1) - { } + : inExec(false) + { + returnCode.store(-1); + exit.store(true); + } QAtomicInt quitLockRef; - bool exit, inExec; - int returnCode; + QBasicAtomicInt exit; // bool + QBasicAtomicInt returnCode; + bool inExec; void ref() { -- cgit v1.2.3