diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-03-03 10:54:40 +0100 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-03-03 14:14:00 +0100 |
commit | cf000d080c61cde44bd84e53ee018f36e33b7257 (patch) | |
tree | 9110090fa532c4fbe165473b3dae3fde4f363071 /src/corelib/kernel | |
parent | 2f2d870fdd1e99d27fda6fa986f7de8a17ad0edf (diff) |
QMetaType: support manual unregistration
QtDeclarative registers types in plugins, and supports un- and reloading
those plugins. Those types would leave pointers to unmapped memory in
the type registry on macOs, which would later cause crashes.
We therefore add private API to manually remove the types from the
registry, which can then be used in declarative.
Lastly, as a precaution for re-registering the types, we reset
QMetaTypeInterface::typeId to 0, as the memory is most likely not reset
to 0 when reloading the plugin.
Change-Id: Ic3fc08759f3d4481dca44a91b33baf3ea9e7198e
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 13 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 3 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype_p.h | 1 |
3 files changed, 17 insertions, 0 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index c81f958e74..154527bbfb 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -669,6 +669,13 @@ void QtMetaTypePrivate::derefAndDestroy(QtPrivate::QMetaTypeInterface *d_ptr) } } +Q_CORE_EXPORT void QtMetaTypePrivate::unsafeUnregister(QtPrivate::QMetaTypeInterface *d_ptr) +{ + if (auto reg = customTypeRegistery()) + reg->unregisterDynamicType(d_ptr->typeId.loadRelaxed()); + d_ptr->typeId = 0; +} + /*! \fn QMetaType::~QMetaType() @@ -1768,6 +1775,12 @@ QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(QT_METATYPE_DECLARE_TEMPLATE_ITER) QT_FOR_EACH_STATIC_CORE_CLASS(QT_METATYPE_DECLARE_TEMPLATE_ITER) QT_FOR_EACH_STATIC_CORE_POINTER(QT_METATYPE_DECLARE_TEMPLATE_ITER) QT_FOR_EACH_STATIC_CORE_TEMPLATE(QT_METATYPE_DECLARE_TEMPLATE_ITER) + +Q_CORE_EXPORT QMetaTypeInterface *QMetaTypeInterface::get(const QMetaType &metatype) +{ + return metatype.d_ptr; +} + #undef QT_METATYPE_DECLARE_TEMPLATE_ITER #endif } diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index b9ab0cbca6..424065d247 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -693,6 +693,7 @@ public: static void unregisterConverterFunction(int from, int to); private: friend class QVariant; + friend class QtPrivate::QMetaTypeInterface; QtPrivate::QMetaTypeInterface *d_ptr = nullptr; }; @@ -2278,6 +2279,8 @@ public: using LegacyRegisterOp = void (*)(); LegacyRegisterOp legacyRegisterOp; + + Q_CORE_EXPORT static QMetaTypeInterface *get(const QMetaType &metatype); }; struct QTypeNormalizer diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index 00d57a7e68..6bac442aea 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -218,6 +218,7 @@ static QtPrivate::QMetaTypeInterface *getInterfaceFromType() return true; void derefAndDestroy(QtPrivate::QMetaTypeInterface *d_ptr); +Q_CORE_EXPORT void unsafeUnregister(QtPrivate::QMetaTypeInterface *d_ptr); } //namespace QtMetaTypePrivate |