diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2020-01-15 08:44:27 -0800 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2020-01-15 13:26:00 -0800 |
commit | 567837a7422fe8d96011fbb3b23e7f34bc344e73 (patch) | |
tree | 3aa450354134bec6742be7d2aeb29bf9f718682e | |
parent | 07c33ab76f353f6dbb6103d7777cbef242b8f3f7 (diff) |
QObject: make the connectedSignals member use QAtomicInteger
The bitfield is always mutated under a mutex lock, so there's no need
for atomic bit operations. This is needed because there's one
outstanding access (in isSignalConnected()) that is done outside the
mutex.
Not needed in 5.14 because commit a5a859e721e7a1d0c5a3ec6abe2db55d9144bb36
removed the bit field altogether.
Fixes: QTBUG-81376
Patch-By: Chris Thornton
Change-Id: Idc3fae4d0f614c389d27fffd15ea1d372968f8f1
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 9 | ||||
-rw-r--r-- | src/corelib/kernel/qobject_p.h | 4 |
2 files changed, 7 insertions, 6 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index d685eaf27f..644f1916c9 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -232,7 +232,7 @@ QObjectPrivate::QObjectPrivate(int version) receiveChildEvents = true; postedEvents = 0; extraData = 0; - connectedSignals[0] = connectedSignals[1] = 0; + // connectedSignals[0] = connectedSignals[1] = 0; // already 0. metaObject = 0; isWindow = false; deleteLaterCalled = false; @@ -411,9 +411,10 @@ void QObjectPrivate::addConnection(int signal, Connection *c) c->next->prev = &c->next; if (signal < 0) { - connectedSignals[0] = connectedSignals[1] = ~0; + connectedSignals[0].store(~0); + connectedSignals[1].store(~0); } else if (signal < (int)sizeof(connectedSignals) * 8) { - connectedSignals[signal >> 5] |= (1 << (signal & 0x1f)); + connectedSignals[signal >> 5].store(connectedSignals[signal >> 5].load() | (1 << (signal & 0x1f))); } } @@ -455,7 +456,7 @@ void QObjectPrivate::cleanConnectionLists() if (!allConnected && !connected && signal >= 0 && size_t(signal) < sizeof(connectedSignals) * 8) { // This signal is no longer connected - connectedSignals[signal >> 5] &= ~(1 << (signal & 0x1f)); + connectedSignals[signal >> 5].store(connectedSignals[signal >> 5].load() & ~(1 << (signal & 0x1f))); } else if (signal == -1) { allConnected = connected; } diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 5dfef786ec..321f358e3c 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -232,7 +232,7 @@ public: Connection *senders; // linked list of connections connected to this object Sender *currentSender; // object currently activating the object - mutable quint32 connectedSignals[2]; + mutable QAtomicInteger<quint32> connectedSignals[2]; union { QObject *currentChildBeingDeleted; // should only be used when QObjectData::isDeletingChildren is set @@ -257,7 +257,7 @@ Q_DECLARE_TYPEINFO(QObjectPrivate::ConnectionList, Q_MOVABLE_TYPE); inline bool QObjectPrivate::isSignalConnected(uint signal_index, bool checkDeclarative) const { return signal_index >= sizeof(connectedSignals) * 8 - || (connectedSignals[signal_index >> 5] & (1 << (signal_index & 0x1f)) + || (connectedSignals[signal_index >> 5].load() & (1 << (signal_index & 0x1f)) || (checkDeclarative && isDeclarativeSignalConnected(signal_index))); } |