summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2020-01-15 08:44:27 -0800
committerThiago Macieira <thiago.macieira@intel.com>2020-01-15 13:26:00 -0800
commit567837a7422fe8d96011fbb3b23e7f34bc344e73 (patch)
tree3aa450354134bec6742be7d2aeb29bf9f718682e /src
parent07c33ab76f353f6dbb6103d7777cbef242b8f3f7 (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>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qobject.cpp9
-rw-r--r--src/corelib/kernel/qobject_p.h4
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)));
}