From d7c9619a815af74a988770c2d2e5d1116f2769fb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 13 Nov 2024 12:56:24 -0800 Subject: [PATCH] QObjectData: relax accesses to postedEvents If one wants to access the event list itself, they have to lock the postedEventList mutex, so none of these probably need any more ordering than Relaxed. I've left most of them in Acquire/Release because we don't have time to reason whether Relaxed suffices (the one exception is a loadRelaxed() that calls a function that does loadAcquire()). Amends commit ba6c1d2785ca6d8a8b162abcd9d978ab0c52ea2d. Pick-to: 6.8 Change-Id: I35810f961b96aaf63d74fffd1eda73b3e059583d Reviewed-by: Fabian Kosmale --- src/corelib/kernel/qcoreapplication.cpp | 17 +++++++++-------- src/corelib/kernel/qobject.cpp | 4 ++-- src/corelib/thread/qthread.cpp | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 2bff9468824..2094e12dc32 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -503,7 +503,7 @@ void QCoreApplicationPrivate::cleanupThreadData() const auto locker = qt_scoped_lock(thisThreadData->postEventList.mutex); for (const QPostEvent &pe : std::as_const(thisThreadData->postEventList)) { if (pe.event) { - --pe.receiver->d_func()->postedEvents; + pe.receiver->d_func()->postedEvents.fetchAndSubAcquire(1); pe.event->m_posted = false; delete pe.event; } @@ -1660,7 +1660,7 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) QThreadData *data = locker.threadData; // if this is one of the compressible events, do compression - if (receiver->d_func()->postedEvents + if (receiver->d_func()->postedEvents.loadAcquire() && self && self->compressEvent(event, receiver, &data->postEventList)) { Q_TRACE(QCoreApplication_postEvent_event_compressed, receiver, event); return; @@ -1673,7 +1673,7 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) data->postEventList.addEvent(QPostEvent(receiver, event, priority)); Q_UNUSED(eventDeleter.release()); event->m_posted = true; - ++receiver->d_func()->postedEvents; + receiver->d_func()->postedEvents.fetchAndAddRelease(1); data->canWait = false; locker.unlock(); @@ -1774,7 +1774,8 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type // events, canWait will be set to false. data->canWait = (data->postEventList.size() == 0); - if (data->postEventList.size() == 0 || (receiver && !receiver->d_func()->postedEvents)) { + if (data->postEventList.size() == 0 + || (receiver && !receiver->d_func()->postedEvents.loadAcquire())) { --data->postEventList.recursion; return; } @@ -1903,7 +1904,7 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type QEvent *e = pe.event; QObject * r = pe.receiver; - --r->d_func()->postedEvents; + r->d_func()->postedEvents.fetchAndSubAcquire(1); Q_ASSERT(r->d_func()->postedEvents >= 0); // next, update the data structure so that we're ready @@ -1954,7 +1955,7 @@ void QCoreApplication::removePostedEvents(QObject *receiver, int eventType) // happen while the event loop is in the middle of posting events, // and when we get here, we may not have any more posted events // for this object. - if (receiver && !receiver->d_func()->postedEvents) + if (receiver && !receiver->d_func()->postedEvents.loadAcquire()) return; //we will collect all the posted events for the QObject @@ -1968,7 +1969,7 @@ void QCoreApplication::removePostedEvents(QObject *receiver, int eventType) if ((!receiver || pe.receiver == receiver) && (pe.event && (eventType == 0 || pe.event->type() == eventType))) { - --pe.receiver->d_func()->postedEvents; + pe.receiver->d_func()->postedEvents.fetchAndSubAcquire(1); pe.event->m_posted = false; events.append(pe.event); const_cast(pe).event = nullptr; @@ -2029,7 +2030,7 @@ void QCoreApplicationPrivate::removePostedEvent(QEvent * event) pe.receiver->metaObject()->className(), pe.receiver->objectName().toLocal8Bit().data()); #endif - --pe.receiver->d_func()->postedEvents; + pe.receiver->d_func()->postedEvents.fetchAndSubAcquire(1); pe.event->m_posted = false; delete pe.event; const_cast(pe).event = nullptr; diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 2a1391f1d52..7c179c4bde5 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -172,7 +172,7 @@ QObjectPrivate::QObjectPrivate(int version) isDeletingChildren = false; // set by deleteChildren() sendChildEvents = true; // if we should send ChildAdded and ChildRemoved events to parent receiveChildEvents = true; - postedEvents = 0; + postedEvents.storeRelaxed(0); extraData = nullptr; metaObject = nullptr; isWindow = false; @@ -200,7 +200,7 @@ QObjectPrivate::~QObjectPrivate() } } - if (postedEvents) + if (postedEvents.loadRelaxed()) QCoreApplication::removePostedEvents(q_ptr, 0); thisThreadData->deref(); diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 61294deee25..5af1787fb11 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -68,7 +68,7 @@ QThreadData::~QThreadData() for (qsizetype i = 0; i < postEventList.size(); ++i) { const QPostEvent &pe = postEventList.at(i); if (pe.event) { - --pe.receiver->d_func()->postedEvents; + pe.receiver->d_func()->postedEvents.fetchAndSubRelaxed(1); pe.event->m_posted = false; delete pe.event; }