diff options
author | Thomas McGuire <thomas.mcguire@kdab.com> | 2014-02-05 16:58:24 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-08 14:32:53 +0100 |
commit | 6f5db32abee3826151b9230ee7dca56ada4a3a89 (patch) | |
tree | 0784416e7ca10b573e4581f7fc73264215cc483a /src/corelib/kernel/qobject.cpp | |
parent | f34b7f42e5c9d2a50da51dbba5fa18467d0262c0 (diff) |
Don't deadlock when deleting slot objects in QMetaObject::activate()
The slot object was deleted after the mutex was relocked, which caused
a deadlock in case the functor destructor locked the same mutex again.
Change-Id: I5b4fb22fdb4483f91c89915872bfd548c31b0eea
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib/kernel/qobject.cpp')
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 43b88d21b5..4cbb618233 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3561,9 +3561,15 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i const int method_relative = c->method_relative; if (c->isSlotObject) { c->slotObj->ref(); - const QScopedPointer<QtPrivate::QSlotObjectBase, QSlotObjectBaseDeleter> obj(c->slotObj); + QScopedPointer<QtPrivate::QSlotObjectBase, QSlotObjectBaseDeleter> obj(c->slotObj); locker.unlock(); obj->call(receiver, argv ? argv : empty_argv); + + // Make sure the slot object gets destroyed before the mutex is locked again, as the + // destructor of the slot object might also lock a mutex from the signalSlotLock() mutex pool, + // and that would deadlock if the pool happens to return the same mutex. + obj.reset(); + locker.relock(); } else if (callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) { //we compare the vtable to make sure we are not in the destructor of the object. |