summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@woboq.com>2013-11-21 18:37:36 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-26 08:29:41 +0100
commit9b8570c4e9359eb8b45b39c28aa9d8c140f3fc44 (patch)
tree5396042f50911706a042c9e71458a7cd6877267f
parentdf449d4f86b152ff471e6fa4cc11182fa409bc0d (diff)
Fix deadlock when disconnecting connections made with function pointersv5.2.0-rc1
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 <thiago.macieira@intel.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/corelib/kernel/qobject.cpp5
1 files changed, 2 insertions, 3 deletions
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<QObject *>(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)