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>
This commit is contained in:
Thiago Macieira 2020-01-15 08:44:27 -08:00
parent 07c33ab76f
commit 567837a742
2 changed files with 7 additions and 6 deletions

View File

@ -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;
}

View File

@ -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)));
}