diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c index 1cbe0da771..12537b6199 100644 --- a/src/3rdparty/forkfd/forkfd.c +++ b/src/3rdparty/forkfd/forkfd.c @@ -519,9 +519,9 @@ static void cleanup() ffd_atomic_store(&forkfd_status, 0, FFD_ATOMIC_RELAXED); /* free any arrays we might have */ - array = children.header.nextArray; + array = ffd_atomic_load(&children.header.nextArray, FFD_ATOMIC_ACQUIRE); while (array != NULL) { - BigArray *next = array->header.nextArray; + BigArray *next = ffd_atomic_load(&array->header.nextArray, FFD_ATOMIC_ACQUIRE); free(array); array = next; } diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 3a29a0d842..1d5b76a8a4 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -517,7 +517,7 @@ void QProcessPrivate::startProcess() if (stderrChannel.pipe[0] != -1) ::fcntl(stderrChannel.pipe[0], F_SETFL, ::fcntl(stderrChannel.pipe[0], F_GETFL) | O_NONBLOCK); - if (threadData->eventDispatcher) { + if (threadData->eventDispatcher.loadAcquire()) { deathNotifier = new QSocketNotifier(forkfd, QSocketNotifier::Read, q); QObject::connect(deathNotifier, SIGNAL(activated(int)), q, SLOT(_q_processDied())); diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 5d300a0488..e5b88c3c26 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -385,8 +385,8 @@ struct QCoreApplicationData { ~QCoreApplicationData() { #ifndef QT_NO_QOBJECT // cleanup the QAdoptedThread created for the main() thread - if (QCoreApplicationPrivate::theMainThread) { - QThreadData *data = QThreadData::get2(QCoreApplicationPrivate::theMainThread); + if (auto *t = QCoreApplicationPrivate::theMainThread.loadAcquire()) { + QThreadData *data = QThreadData::get2(t); data->deref(); // deletes the data and the adopted thread } #endif @@ -486,7 +486,7 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint #endif QThread *cur = QThread::currentThread(); // note: this may end up setting theMainThread! - if (cur != theMainThread) + if (cur != theMainThread.loadAcquire()) qWarning("WARNING: QApplication was not created in the main() thread."); #endif } @@ -862,7 +862,7 @@ void QCoreApplicationPrivate::init() Q_ASSERT(eventDispatcher); if (!eventDispatcher->parent()) { - eventDispatcher->moveToThread(threadData->thread); + eventDispatcher->moveToThread(threadData->thread.loadAcquire()); eventDispatcher->setParent(q); } @@ -1181,7 +1181,7 @@ static bool doNotify(QObject *receiver, QEvent *event) bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event) { // We can't access the application event filters outside of the main thread (race conditions) - Q_ASSERT(receiver->d_func()->threadData->thread == mainThread()); + Q_ASSERT(receiver->d_func()->threadData->thread.loadAcquire() == mainThread()); if (extraData) { // application event filters are only called for objects in the GUI thread @@ -1234,7 +1234,7 @@ bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event) // send to all application event filters (only does anything in the main thread) if (QCoreApplication::self - && receiver->d_func()->threadData->thread == mainThread() + && receiver->d_func()->threadData->thread.loadAcquire() == mainThread() && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) { filtered = true; return filtered; @@ -2905,7 +2905,7 @@ void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filt return; } - QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread); + QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread.loadAcquire()); if (!filterObj || !eventDispatcher) return; eventDispatcher->installNativeEventFilter(filterObj); @@ -2961,7 +2961,7 @@ bool QCoreApplication::hasPendingEvents() */ QAbstractEventDispatcher *QCoreApplication::eventDispatcher() { - if (QCoreApplicationPrivate::theMainThread) + if (QCoreApplicationPrivate::theMainThread.loadAcquire()) return QCoreApplicationPrivate::theMainThread.loadRelaxed()->eventDispatcher(); return 0; } @@ -2974,7 +2974,7 @@ QAbstractEventDispatcher *QCoreApplication::eventDispatcher() */ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher) { - QThread *mainThread = QCoreApplicationPrivate::theMainThread; + QThread *mainThread = QCoreApplicationPrivate::theMainThread.loadAcquire(); if (!mainThread) mainThread = QThread::currentThread(); // will also setup theMainThread mainThread->setEventDispatcher(eventDispatcher); diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index 2104b22095..eacd0c4e73 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -165,7 +165,7 @@ int QEventLoop::exec(ProcessEventsFlags flags) { Q_D(QEventLoop); //we need to protect from race condition with QThread::exit - QMutexLocker locker(&static_cast(QObjectPrivate::get(d->threadData->thread))->mutex); + QMutexLocker locker(&static_cast(QObjectPrivate::get(d->threadData->thread.loadAcquire()))->mutex); if (d->threadData->quitNow) return -1; diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 1540ebfe12..9a2ae36177 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -219,7 +219,7 @@ QObjectPrivate::QObjectPrivate(int version) QObjectPrivate::~QObjectPrivate() { if (extraData && !extraData->runningTimers.isEmpty()) { - if (Q_LIKELY(threadData->thread == QThread::currentThread())) { + if (Q_LIKELY(threadData->thread.loadAcquire() == QThread::currentThread())) { // unregister pending timers if (threadData->hasEventDispatcher()) threadData->eventDispatcher.loadRelaxed()->unregisterTimers(q_ptr); @@ -493,11 +493,11 @@ bool QObjectPrivate::maybeSignalConnected(uint signalIndex) const if (!signalVector) return false; - if (signalVector->at(-1).first) + if (signalVector->at(-1).first.loadAcquire()) return true; if (signalIndex < uint(cd->signalVectorCount())) { - const QObjectPrivate::Connection *c = signalVector->at(signalIndex).first; + const QObjectPrivate::Connection *c = signalVector->at(signalIndex).first.loadAcquire(); return c != nullptr; } return false; @@ -819,8 +819,8 @@ static bool check_parent_thread(QObject *parent, QThreadData *currentThreadData) { if (parent && parentThreadData != currentThreadData) { - QThread *parentThread = parentThreadData->thread; - QThread *currentThread = currentThreadData->thread; + QThread *parentThread = parentThreadData->thread.loadAcquire(); + QThread *currentThread = currentThreadData->thread.loadAcquire(); qWarning("QObject: Cannot create children for a parent that is in a different thread.\n" "(Parent is %s(%p), parent's thread is %s(%p), current thread is %s(%p)", parent->metaObject()->className(), @@ -987,11 +987,11 @@ QObject::~QObject() QObjectPrivate::ConnectionList &connectionList = cd->connectionsForSignal(signal); while (QObjectPrivate::Connection *c = connectionList.first.loadRelaxed()) { - Q_ASSERT(c->receiver); + Q_ASSERT(c->receiver.loadAcquire()); QBasicMutex *m = signalSlotLock(c->receiver.loadRelaxed()); bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m); - if (c->receiver) { + if (c->receiver.loadAcquire()) { cd->removeConnection(c); Q_ASSERT(connectionList.first.loadRelaxed() != c); } @@ -1003,7 +1003,7 @@ QObject::~QObject() /* Disconnect all senders: */ while (QObjectPrivate::Connection *node = cd->senders) { - Q_ASSERT(node->receiver); + Q_ASSERT(node->receiver.loadAcquire()); QObject *sender = node->sender; // Send disconnectNotify before removing the connection from sender's connection list. // This ensures any eventual destructor of sender will block on getting receiver's lock @@ -1453,7 +1453,7 @@ bool QObject::blockSignals(bool block) noexcept */ QThread *QObject::thread() const { - return d_func()->threadData->thread; + return d_func()->threadData->thread.loadAcquire(); } /*! @@ -1500,7 +1500,7 @@ void QObject::moveToThread(QThread *targetThread) { Q_D(QObject); - if (d->threadData->thread == targetThread) { + if (d->threadData->thread.loadAcquire() == targetThread) { // object is already in this thread return; } @@ -1516,7 +1516,7 @@ void QObject::moveToThread(QThread *targetThread) QThreadData *currentData = QThreadData::current(); QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : nullptr; - if (d->threadData->thread == 0 && currentData == targetData) { + if (d->threadData->thread.loadAcquire() == 0 && currentData == targetData) { // one exception to the rule: we allow moving objects with no thread affinity to the current thread currentData = d->threadData; } else if (d->threadData != currentData) { @@ -3716,7 +3716,7 @@ void doActivate(QObject *sender, int signal_index, void **argv) bool senderDeleted = false; { - Q_ASSERT(sp->connections); + Q_ASSERT(sp->connections.loadAcquire()); QObjectPrivate::ConnectionDataPointer connections(sp->connections.loadRelaxed()); QObjectPrivate::SignalVector *signalVector = connections->signalVector.loadRelaxed(); @@ -3773,7 +3773,7 @@ void doActivate(QObject *sender, int signal_index, void **argv) QSemaphore semaphore; { QBasicMutexLocker locker(signalSlotLock(sender)); - if (!c->receiver) + if (!c->receiver.loadAcquire()) continue; QMetaCallEvent *ev = c->isSlotObject ? new QMetaCallEvent(c->slotObj, sender, signal_index, 0, 0, argv, &semaphore) : diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 247c7b1501..9cf1bfed08 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -312,7 +312,7 @@ public: } } int signalVectorCount() const { - return signalVector ? signalVector.loadRelaxed()->count() : -1; + return signalVector.loadAcquire() ? signalVector.loadRelaxed()->count() : -1; } static void deleteOrphaned(ConnectionOrSignalVector *c); diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 1eac7db11d..fe555afca7 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -73,8 +73,8 @@ QThreadData::~QThreadData() // crashing during QCoreApplicationData's global static cleanup we need to // safeguard the main thread here.. This fix is a bit crude, but it solves // the problem... - if (this->thread == QCoreApplicationPrivate::theMainThread) { - QCoreApplicationPrivate::theMainThread = 0; + if (this->thread.loadAcquire() == QCoreApplicationPrivate::theMainThread.loadAcquire()) { + QCoreApplicationPrivate::theMainThread.storeRelease(nullptr); QThreadData::clearCurrentThreadData(); } @@ -85,8 +85,8 @@ QThreadData::~QThreadData() // because this destructor is still running (the _ref sub-object has not // been destroyed) and there's no reentrancy. The refcount will become // negative, but that's acceptable. - QThread *t = thread; - thread = 0; + QThread *t = thread.loadAcquire(); + thread.storeRelease(nullptr); delete t; for (int i = 0; i < postEventList.size(); ++i) { @@ -393,7 +393,7 @@ QThread *QThread::currentThread() { QThreadData *data = QThreadData::current(); Q_ASSERT(data != 0); - return data->thread; + return data->thread.loadAcquire(); } /*! @@ -980,7 +980,7 @@ bool QThread::event(QEvent *event) void QThread::requestInterruption() { - if (this == QCoreApplicationPrivate::theMainThread) { + if (this == QCoreApplicationPrivate::theMainThread.loadAcquire()) { qWarning("QThread::requestInterruption has no effect on the main thread"); return; } diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 89efbff6aa..38e9c1c3ec 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -141,7 +141,7 @@ static void destroy_current_thread_data(void *p) pthread_setspecific(current_thread_data_key, p); QThreadData *data = static_cast(p); if (data->isAdopted) { - QThread *thread = data->thread; + QThread *thread = data->thread.loadAcquire(); Q_ASSERT(thread); QThreadPrivate *thread_p = static_cast(QObjectPrivate::get(thread)); Q_ASSERT(!thread_p->finished); @@ -253,8 +253,8 @@ QThreadData *QThreadData::current(bool createIfNecessary) data->deref(); data->isAdopted = true; data->threadId.storeRelaxed(to_HANDLE(pthread_self())); - if (!QCoreApplicationPrivate::theMainThread) - QCoreApplicationPrivate::theMainThread = data->thread.loadRelaxed(); + if (!QCoreApplicationPrivate::theMainThread.loadAcquire()) + QCoreApplicationPrivate::theMainThread.storeRelease(data->thread.loadRelaxed()); } return data; } @@ -285,7 +285,7 @@ QAbstractEventDispatcher *QThreadPrivate::createEventDispatcher(QThreadData *dat else return new QEventDispatcherUNIX; #elif !defined(QT_NO_GLIB) - const bool isQtMainThread = data->thread == QCoreApplicationPrivate::mainThread(); + const bool isQtMainThread = data->thread.loadAcquire() == QCoreApplicationPrivate::mainThread(); if (qEnvironmentVariableIsEmpty("QT_NO_GLIB") && (isQtMainThread || qEnvironmentVariableIsEmpty("QT_NO_THREADED_GLIB")) && QEventDispatcherGlib::versionSupported()) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 22ebeaae51..58f63c0fed 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3666,7 +3666,7 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e) // send to all application event filters if (threadRequiresCoreApplication() - && receiver->d_func()->threadData->thread == mainThread() + && receiver->d_func()->threadData->thread.loadAcquire() == mainThread() && sendThroughApplicationEventFilters(receiver, e)) { filtered = true; return filtered;