diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-08-24 14:52:30 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-08-28 13:49:14 +0200 |
commit | 229987d91505203e5a1577651b65880e58239ac7 (patch) | |
tree | 4a42a347a831824d2ffc8f8dee6a90a0dd7d0859 /src/qml/qml/qqmlmetatype.cpp | |
parent | 2afed94c70913e018198422ef222c9168326d09c (diff) |
Do proper memory management on the metatype interfaces we create
Those interfaces are always registered in pairs. Add an external
refcount to CompositeMetaTypeIds, and do registration and
de-registration through this class.
Change-Id: I4f3a53ad935a43a734d6506ffc768f507b48ee1f
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlmetatype.cpp')
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index cb2522a675..06fdb0fab0 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -54,6 +54,32 @@ Q_DECLARE_LOGGING_CATEGORY(DBG_DISK_CACHE) QT_BEGIN_NAMESPACE +CompositeMetaTypeIds CompositeMetaTypeIds::fromCompositeName(const QByteArray &name) +{ + auto ids = QQmlMetaType::registerInternalCompositeType(name); + ids.refCount = new int; + *ids.refCount = 1; + return ids; +} + +void CompositeMetaTypeIds::deref() +{ + Q_ASSERT(refCount); + --*refCount; + if (!*refCount) { + delete refCount; + QQmlMetaType::unregisterInternalCompositeType(*this); + refCount = nullptr; + } +} + +CompositeMetaTypeIds::~CompositeMetaTypeIds() +{ + if (refCount) + deref(); +} + + struct LockedData : private QQmlMetaTypeData { friend class QQmlMetaTypeDataPtr; @@ -542,11 +568,11 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit -template <typename T> struct QQmlMetaTypeInterface : QtPrivate::QMetaTypeInterface { const QByteArray name; - QQmlMetaTypeInterface(const QByteArray &name) + template <typename T> + QQmlMetaTypeInterface(const QByteArray &name, T *) : QMetaTypeInterface { /*.revision=*/ 0, /*.alignment=*/ alignof(T), @@ -580,8 +606,8 @@ CompositeMetaTypeIds QQmlMetaType::registerInternalCompositeType(const QByteArra QByteArray ptr = className + '*'; QByteArray lst = "QQmlListProperty<" + className + '>'; - QMetaType ptr_type(new QQmlMetaTypeInterface<QObject*>(ptr)); - QMetaType lst_type(new QQmlMetaTypeInterface<QQmlListProperty<QObject>>(lst)); + QMetaType ptr_type(new QQmlMetaTypeInterface(ptr, (QObject **)nullptr)); + QMetaType lst_type(new QQmlMetaTypeInterface(lst, (QQmlListProperty<QObject> *)nullptr)); QQmlMetaTypeDataPtr data; data->qmlLists.insert(lst_type.id(), ptr_type.id()); @@ -593,6 +619,8 @@ void QQmlMetaType::unregisterInternalCompositeType(const CompositeMetaTypeIds &t { QQmlMetaTypeDataPtr data; data->qmlLists.remove(typeIds.listId.id()); + delete static_cast<QQmlMetaTypeInterface *>(QMetaType(typeIds.id).iface()); + delete static_cast<QQmlMetaTypeInterface *>(QMetaType(typeIds.listId).iface()); } int QQmlMetaType::registerUnitCacheHook( |