summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qobject_p.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2019-01-07 15:05:06 +0100
committerLars Knoll <lars.knoll@qt.io>2019-02-08 21:55:29 +0000
commit5cc6f90910082f35e3f5340493facbc8c175f65f (patch)
tree9b07659bdb85797471ecaec46fe815415a293cac /src/corelib/kernel/qobject_p.h
parentab92b9e40025dcf08c14232de762a268201a78b4 (diff)
Move all connection related data into one data structure
Adn create that data structure on demand on the heap. This reduces the size of QObjectPrivate if there are no connections. If we have connections, it'll use the same amount of allocations and memory as before. Change-Id: I900f6980a2cd8a5f72c3ad18697b5dd49100217d Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib/kernel/qobject_p.h')
-rw-r--r--src/corelib/kernel/qobject_p.h47
1 files changed, 40 insertions, 7 deletions
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index ab20064c65..64998797ac 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -171,14 +171,15 @@ public:
: receiver(receiver), sender(sender), signal(signal)
{
if (receiver) {
- previous = receiver->d_func()->currentSender;
- receiver->d_func()->currentSender = this;
+ ConnectionData *cd = receiver->d_func()->connections.load();
+ previous = cd->currentSender;
+ cd->currentSender = this;
}
}
~Sender()
{
if (receiver)
- receiver->d_func()->currentSender = previous;
+ receiver->d_func()->connections.load()->currentSender = previous;
}
void receiverDeleted()
{
@@ -194,6 +195,34 @@ public:
int signal;
};
+ /*
+ This contains the all connections from and to an object.
+
+ The signalVector contains the lists of connections for a given signal. The index in the vector correspond
+ to the signal index. The signal index is the one returned by QObjectPrivate::signalIndex (not
+ QMetaObject::indexOfSignal). allsignals contains a list of special connections that will get invoked on
+ any signal emission. This is done by connecting to signal index -1.
+
+ This vector is protected by the object mutex (signalSlotLock())
+
+ Each Connection is also part of a 'senders' linked list. This one contains all connections connected
+ to a slot in this object. The mutex of the receiver must be locked when touching the pointers of this
+ linked list.
+ */
+ struct ConnectionData {
+ bool orphaned = false; //the QObject owner of this vector has been destroyed while the vector was inUse
+ bool dirty = false; //some Connection have been disconnected (their receiver is 0) but not removed from the list yet
+ int inUse = 0; //number of functions that are currently accessing this object or its connections
+ ConnectionList allsignals;
+ QVector<ConnectionList> signalVector;
+ Connection *senders = nullptr;
+ Sender *currentSender = nullptr; // object currently activating the object
+
+ ConnectionList &connectionsForSignal(int signal)
+ {
+ return signal < 0 ? allsignals : signalVector[signal];
+ }
+ };
QObjectPrivate(int version = QObjectPrivateVersion);
virtual ~QObjectPrivate();
@@ -240,14 +269,18 @@ public:
const int *types, const QMetaObject *senderMetaObject);
static QMetaObject::Connection connect(const QObject *sender, int signal_index, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type);
static bool disconnect(const QObject *sender, int signal_index, void **slot);
+
+ void ensureConnectionData()
+ {
+ if (connections.load())
+ return;
+ connections.store(new ConnectionData);
+ }
public:
ExtraData *extraData; // extra data set by the user
QThreadData *threadData; // id of the thread that owns the object
- QObjectConnectionListVector *connectionLists;
-
- Connection *senders; // linked list of connections connected to this object
- Sender *currentSender; // object currently activating the object
+ QAtomicPointer<ConnectionData> connections;
union {
QObject *currentChildBeingDeleted; // should only be used when QObjectData::isDeletingChildren is set