Skip to content

Commit

Permalink
QObjectData: relax accesses to postedEvents
Browse files Browse the repository at this point in the history
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 ba6c1d2.

Pick-to: 6.8
Change-Id: I35810f961b96aaf63d74fffd1eda73b3e059583d
Reviewed-by: Fabian Kosmale <[email protected]>
  • Loading branch information
thiagomacieira committed Dec 5, 2024
1 parent 083e443 commit d7c9619
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 11 deletions.
17 changes: 9 additions & 8 deletions src/corelib/kernel/qcoreapplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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();

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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<QPostEvent &>(pe).event = nullptr;
Expand Down Expand Up @@ -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<QPostEvent &>(pe).event = nullptr;
Expand Down
4 changes: 2 additions & 2 deletions src/corelib/kernel/qobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -200,7 +200,7 @@ QObjectPrivate::~QObjectPrivate()
}
}

if (postedEvents)
if (postedEvents.loadRelaxed())
QCoreApplication::removePostedEvents(q_ptr, 0);

thisThreadData->deref();
Expand Down
2 changes: 1 addition & 1 deletion src/corelib/thread/qthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit d7c9619

Please sign in to comment.