aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/pyside2/libpyside/dynamicqmetaobject.cpp4
-rw-r--r--sources/pyside2/libpyside/signalmanager.cpp15
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);