diff options
-rw-r--r-- | sources/pyside2/libpyside/dynamicqmetaobject.cpp | 4 | ||||
-rw-r--r-- | sources/pyside2/libpyside/signalmanager.cpp | 15 |
2 files changed, 18 insertions, 1 deletions
diff --git a/sources/pyside2/libpyside/dynamicqmetaobject.cpp b/sources/pyside2/libpyside/dynamicqmetaobject.cpp index 2c5a0ee05..51e6598b3 100644 --- a/sources/pyside2/libpyside/dynamicqmetaobject.cpp +++ b/sources/pyside2/libpyside/dynamicqmetaobject.cpp @@ -413,6 +413,10 @@ const QMetaObject *MetaObjectBuilderPrivate::update() if (!m_builder) return m_baseObject; if (m_cachedMetaObjects.empty() || m_dirty) { + // PYSIDE-803: The dirty branch needs to be protected by the GIL. + // This was moved from SignalManager::retrieveMetaObject to here, + // which is only the update in "return builder->update()". + Shiboken::GilState gil; m_cachedMetaObjects.push_back(m_builder->toMetaObject()); checkMethodOrder(m_cachedMetaObjects.back()); m_dirty = false; diff --git a/sources/pyside2/libpyside/signalmanager.cpp b/sources/pyside2/libpyside/signalmanager.cpp index c21a3e565..01b347a3d 100644 --- a/sources/pyside2/libpyside/signalmanager.cpp +++ b/sources/pyside2/libpyside/signalmanager.cpp @@ -550,6 +550,12 @@ bool SignalManager::registerMetaMethod(QObject *source, const char *signature, Q static MetaObjectBuilder *metaBuilderFromDict(PyObject *dict) { + // PYSIDE-803: The dict in this function is the ob_dict of an SbkObject. + // The "metaObjectAttr" entry is only handled in this file. There is no + // way in this function to involve the interpreter. Therefore, we need + // no GIL. + // Note that "SignalManager::registerMetaMethodGetIndex" has write actions + // that might involve the interpreter, but in that context the GIL is held. if (!dict || !PyDict_Contains(dict, metaObjectAttr)) return nullptr; @@ -605,7 +611,14 @@ int SignalManager::registerMetaMethodGetIndex(QObject *source, const char *signa const QMetaObject *SignalManager::retrieveMetaObject(PyObject *self) { - Shiboken::GilState gil; + // PYSIDE-803: Avoid the GIL in SignalManager::retrieveMetaObject + // This function had the GIL. We do not use the GIL unless we have to. + // metaBuilderFromDict accesses a Python dict, but in that context there + // is no way to reach the interpreter, see "metaBuilderFromDict". + // + // The update function is MetaObjectBuilderPrivate::update in + // dynamicmetaobject.c . That function now uses the GIL when the + // m_dirty flag is set. Q_ASSERT(self); MetaObjectBuilder *builder = metaBuilderFromDict(reinterpret_cast<SbkObject *>(self)->ob_dict); |