From 0c64d1b2c6e5e0951675ad9b22294db4a10741c7 Mon Sep 17 00:00:00 2001 From: Pankaj Pandey Date: Thu, 1 May 2014 19:58:03 +0530 Subject: PYSIDE-164: Fix possible deadlock on signal connect/emit Signal connect/emit acquire a lock on the QObject, and can happen from python code (which has acquired the GIL) or internal QtCode (without acquiring the GIL). So we always need to release the GIL to prevent out-of-order acquisition of the locks causing deadlock. Change-Id: I1cf47a73c2b60627e322d8ef3fa4c3efdebd4c02 Reviewed-by: John Ehresman --- PySide/QtCore/glue/qobject_connect.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'PySide/QtCore/glue/qobject_connect.cpp') diff --git a/PySide/QtCore/glue/qobject_connect.cpp b/PySide/QtCore/glue/qobject_connect.cpp index 96bcfb227..f7bb5faaf 100644 --- a/PySide/QtCore/glue/qobject_connect.cpp +++ b/PySide/QtCore/glue/qobject_connect.cpp @@ -61,7 +61,11 @@ static bool qobjectConnect(QObject* source, const char* signal, QObject* receive bool isSignal = PySide::Signal::isQtSignal(slot); slot++; PySide::SignalManager::registerMetaMethod(receiver, slot, isSignal ? QMetaMethod::Signal : QMetaMethod::Slot); - return QObject::connect(source, signal - 1, receiver, slot - 1, type); + bool connected; + Py_BEGIN_ALLOW_THREADS + connected = QObject::connect(source, signal - 1, receiver, slot - 1, type); + Py_END_ALLOW_THREADS + return connected; } static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject* callback, Qt::ConnectionType type) @@ -109,7 +113,11 @@ static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject return false; } } - if (QMetaObject::connect(source, signalIndex, receiver, slotIndex, type)) { + bool connected; + Py_BEGIN_ALLOW_THREADS + connected = QMetaObject::connect(source, signalIndex, receiver, slotIndex, type); + Py_END_ALLOW_THREADS + if (connected) { if (usingGlobalReceiver) signalManager.notifyGlobalReceiver(receiver); #ifndef AVOID_PROTECTED_HACK @@ -151,7 +159,12 @@ static bool qobjectDisconnectCallback(QObject* source, const char* signal, PyObj slotIndex = metaObject->indexOfSlot(callbackSig); - if (QMetaObject::disconnectOne(source, signalIndex, receiver, slotIndex)) { + bool disconnected; + Py_BEGIN_ALLOW_THREADS + disconnected = QMetaObject::disconnectOne(source, signalIndex, receiver, slotIndex); + Py_END_ALLOW_THREADS + + if (disconnected) { if (usingGlobalReceiver) signalManager.releaseGlobalReceiver(source, receiver); -- cgit v1.2.3