From ec6556a2b99df373eb43ca009340a7f0f19bacbd Mon Sep 17 00:00:00 2001 From: David Faure Date: Sat, 1 Aug 2015 15:50:00 +0200 Subject: Fix two data races in QThread/QThreadData * theMainThread is written by the main thread and read by QThreadData::~QThreadData() (any managed thread) * QThreadData::thread is written by QThread::~QThread (in the parent thread) and read+written by QThreadData::~QThreadData (in the managed thread). This can happen because QThreadData is refcounted so the managed thread (which derefs it) races with the parent thread (which sets it to 0). Change-Id: I72de793716391a0937254cda6b4328fcad5060c7 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qcoreapplication.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/corelib/kernel/qcoreapplication.cpp') diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 37a26cf556..24427bd1af 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -460,8 +460,8 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint qt_application_thread_id = QThread::currentThreadId(); # endif - // note: this call to QThread::currentThread() may end up setting theMainThread! - if (QThread::currentThread() != theMainThread) + QThread *cur = QThread::currentThread(); // note: this may end up setting theMainThread! + if (cur != theMainThread) qWarning("WARNING: QApplication was not created in the main() thread."); #endif } @@ -531,11 +531,11 @@ void QCoreApplicationPrivate::eventDispatcherReady() { } -QThread *QCoreApplicationPrivate::theMainThread = 0; +QBasicAtomicPointer QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(0); QThread *QCoreApplicationPrivate::mainThread() { - Q_ASSERT(theMainThread != 0); - return theMainThread; + Q_ASSERT(theMainThread.load() != 0); + return theMainThread.load(); } void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver) @@ -2671,7 +2671,7 @@ bool QCoreApplication::hasPendingEvents() QAbstractEventDispatcher *QCoreApplication::eventDispatcher() { if (QCoreApplicationPrivate::theMainThread) - return QCoreApplicationPrivate::theMainThread->eventDispatcher(); + return QCoreApplicationPrivate::theMainThread.load()->eventDispatcher(); return 0; } -- cgit v1.2.3