From 9b8570c4e9359eb8b45b39c28aa9d8c140f3fc44 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 21 Nov 2013 18:37:36 +0100 Subject: Fix deadlock when disconnecting connections made with function pointers The regression was introduced in 5885b8f775998c30d53f40b7f368c5f6364e6df4 QMetaObjectPrivate::disconnectHelper may unlock the sender mutex. And while relocking it, we need to make sure to lock the sender and receiver mutex in the right order. So don't lock the receiver mutex in advance, but re-lock it for each connection. Change-Id: I4f6d19791cdcce3693d7f45e7beb6b564fd69277 Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- src/corelib/kernel/qobject.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/corelib/kernel/qobject.cpp') diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 777f95ef6d..e062a38185 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3181,7 +3181,7 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c, && (slot == 0 || (c->isSlotObject && c->slotObj->compare(slot)))))) { bool needToUnlock = false; QMutex *receiverMutex = 0; - if (!receiver) { + if (c->receiver) { receiverMutex = signalSlotLock(c->receiver); // need to relock this receiver and sender in the correct order needToUnlock = QOrderedMutexLocker::relock(senderMutex, receiverMutex); @@ -3229,8 +3229,7 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender, QObject *s = const_cast(sender); QMutex *senderMutex = signalSlotLock(sender); - QMutex *receiverMutex = receiver ? signalSlotLock(receiver) : 0; - QOrderedMutexLocker locker(senderMutex, receiverMutex); + QMutexLocker locker(senderMutex); QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists; if (!connectionLists) -- cgit v1.2.3