diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-09-18 10:57:47 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-10-15 07:21:36 +0000 |
commit | 6bfbfd6edd0f9701664698768f9ec8d29f96a5bd (patch) | |
tree | dbd9d10d8f67243be79fea6d0e32536b79ba83b9 /sources/shiboken2/ApiExtractor | |
parent | 954fe04e4d4cb3f00d2891dc1a0843e91b115e7f (diff) |
Fix crash when garbage collecting in a non-GUI thread
If a GUI class happens to be detected unreferenced when garbage
collecting in a non-GUI thread and is subsequently deleted, crashes
can occur for QWidgets and similar classes.
The hitherto unimplemented delete-in-main-thread" attribute should be
used.
Add the missing implementation. Add the field to shiboken's type entry
and SbkObjectTypePrivate class and pass it via newly introduced flags
to introduceWrapperType().
Defer the deletion when invoked from the background thread and store
the list of destructors in a list in binding manager run by
Py_AddPendingCall().
Task-number: PYSIDE-743
Task-number: PYSIDE-810
Change-Id: Id4668a6a1e32392be9dcf1229e1e10c492b2a5f5
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'sources/shiboken2/ApiExtractor')
-rw-r--r-- | sources/shiboken2/ApiExtractor/abstractmetalang.cpp | 7 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/abstractmetalang.h | 2 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/typedatabase.cpp | 1 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/typesystem.cpp | 7 | ||||
-rw-r--r-- | sources/shiboken2/ApiExtractor/typesystem.h | 4 |
5 files changed, 18 insertions, 3 deletions
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index 35e12f780..c65d7e0bd 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -1613,6 +1613,13 @@ void AbstractMetaClass::setTemplateBaseClassInstantiations(AbstractMetaTypeList& metaClassBaseTemplateInstantiations()->insert(this, instantiations); } +// Does any of the base classes require deletion in the main thread? +bool AbstractMetaClass::deleteInMainThread() const +{ + return typeEntry()->deleteInMainThread() + || (m_baseClass && m_baseClass->deleteInMainThread()); +} + static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func) { for (const AbstractMetaFunction *f : l) { diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index 42129e9b7..aaefa32d5 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -1699,6 +1699,8 @@ public: return m_hasToStringCapability; } + bool deleteInMainThread() const; + static AbstractMetaClass *findClass(const AbstractMetaClassList &classes, const QString &name); static AbstractMetaClass *findClass(const AbstractMetaClassList &classes, diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp index 69cddca4c..dcfd9f740 100644 --- a/sources/shiboken2/ApiExtractor/typedatabase.cpp +++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp @@ -782,6 +782,7 @@ void ComplexTypeEntry::formatDebug(QDebug &d) const FORMAT_BOOL("QObject", m_qobject) FORMAT_BOOL("polymorphicBase", m_polymorphicBase) FORMAT_BOOL("genericClass", m_genericClass) + FORMAT_BOOL("deleteInMainThread", m_deleteInMainThread) if (m_typeFlags != 0) d << ", typeFlags=" << m_typeFlags; d << ", copyableFlag=" << m_copyableFlag diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp index ba219cf5f..21c35bda6 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.cpp +++ b/sources/shiboken2/ApiExtractor/typesystem.cpp @@ -1301,8 +1301,8 @@ void Handler::applyComplexTypeAttributes(const QXmlStreamReader &reader, if (convertBoolean(attributes->takeAt(i).value(), deprecatedAttribute(), false)) ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::Deprecated); } else if (name == deleteInMainThreadAttribute()) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, name))); + if (convertBoolean(attributes->takeAt(i).value(), deleteInMainThreadAttribute(), false)) + ctype->setDeleteInMainThread(true); } else if (name == QLatin1String("target-type")) { ctype->setTargetType(attributes->takeAt(i).value().toString()); } @@ -3221,7 +3221,8 @@ ComplexTypeEntry::ComplexTypeEntry(const QString &name, TypeEntry::Type t, m_qualifiedCppName(name), m_qobject(false), m_polymorphicBase(false), - m_genericClass(false) + m_genericClass(false), + m_deleteInMainThread(false) { } diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h index 028f016f3..721d19f29 100644 --- a/sources/shiboken2/ApiExtractor/typesystem.h +++ b/sources/shiboken2/ApiExtractor/typesystem.h @@ -1346,6 +1346,9 @@ public: m_genericClass = isGeneric; } + bool deleteInMainThread() const { return m_deleteInMainThread; } + void setDeleteInMainThread(bool d) { m_deleteInMainThread = d; } + CopyableFlag copyable() const { return m_copyableFlag; @@ -1403,6 +1406,7 @@ private: uint m_qobject : 1; uint m_polymorphicBase : 1; uint m_genericClass : 1; + uint m_deleteInMainThread : 1; QString m_polymorphicIdValue; QString m_lookupName; |