Fix race condition between destruction of QObjects
If the two QObjecs are connected and destroyed at the same time, it is possible to hit a case where QObject::metaObject and QObject::disconnectNotify is called on a destroyed object. This patch moves the calls up before the removal of the connection. This ensure the sender object will have to block on the receivers connection mutex and can not finish destruction before disconnectNotify is called. Task-number: QTBUG-34131 Change-Id: I398116fe7bc6a195991aff9961d89a8b0ac8d53c Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
parent
bb090fa76e
commit
3f97e38440
@ -868,6 +868,10 @@ QObject::~QObject()
|
||||
QObjectPrivate::Connection *node = d->senders;
|
||||
while (node) {
|
||||
QObject *sender = node->sender;
|
||||
// Send disconnectNotify before removing the connection from sender's connection list.
|
||||
// This ensures any eventual destructor of sender will block on getting receiver's lock
|
||||
// and not finish until we release it.
|
||||
sender->disconnectNotify(QMetaObjectPrivate::signal(sender->metaObject(), node->signal_index));
|
||||
QMutex *m = signalSlotLock(sender);
|
||||
node->prev = &node;
|
||||
bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
|
||||
@ -881,8 +885,6 @@ QObject::~QObject()
|
||||
if (senderLists)
|
||||
senderLists->dirty = true;
|
||||
|
||||
int signal_index = node->signal_index;
|
||||
|
||||
QtPrivate::QSlotObjectBase *slotObj = Q_NULLPTR;
|
||||
if (node->isSlotObject) {
|
||||
slotObj = node->slotObj;
|
||||
@ -899,7 +901,6 @@ QObject::~QObject()
|
||||
locker.relock();
|
||||
}
|
||||
|
||||
sender->disconnectNotify(QMetaObjectPrivate::signal(sender->metaObject(), signal_index));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user