From b5b5782088c25c67f090500d71fa1ae655383553 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 10 Mar 2022 12:49:35 +0100 Subject: QML: Add more safety to QQmlPropertyCache usages We can almost always use QQmlPropertyCache::ConstPtr. The property cache creator needs mutable property caches for a while, but it can seal them when done. The designer integration does ugly stuff, but that should be limited to a specific environment. And the QQmlOpenMetaObject is rather wrong (again). This needs to be addresses in a later change. Task-number: QTBUG-73271 Change-Id: I1c31fd5936c745029d25b909c30b8d14a30f25d3 Reviewed-by: Andrei Golubev Reviewed-by: Qt CI Bot Reviewed-by: Fabian Kosmale --- src/qml/qml/qqmlmetatype_p.h | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'src/qml/qml/qqmlmetatype_p.h') diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 1fb4d915da..3c71e2c583 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -122,6 +122,8 @@ public: class Q_QML_PRIVATE_EXPORT QQmlMetaType { friend struct CompositeMetaTypeIds; + friend class QQmlDesignerMetaObject; + static CompositeMetaTypeIds registerInternalCompositeType(const QByteArray &className); static void unregisterInternalCompositeType(const CompositeMetaTypeIds &typeIds); @@ -176,19 +178,34 @@ public: static QQmlType qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports = false); - static QQmlRefPointer propertyCache( + static QQmlPropertyCache::ConstPtr propertyCache( QObject *object, QTypeRevision version = QTypeRevision()); - static QQmlRefPointer propertyCache( + static QQmlPropertyCache::ConstPtr propertyCache( const QMetaObject *metaObject, QTypeRevision version = QTypeRevision()); - static QQmlRefPointer propertyCache( + static QQmlPropertyCache::ConstPtr propertyCache( const QQmlType &type, QTypeRevision version); + // This only works for a new metaObject that doesn't have an associated property cache, yet. + // Do not call it more than once for the same metaObject! + // + // ------------------------------------------------------------------------------------ + // --> The caller has to uphold the immutability guarantees for the returned property cache <-- + // ------------------------------------------------------------------------------------ + // + // This means: You cannot expose the metaObject, any objects created from it, or the property + // cache to _anything_ that allows concurrent access before you are done changing the property + // cache! + // + // In general, don't use this method. It's only for the designer integration. The designer + // assumes that there is only one QML engine running in a single thread. + static QQmlPropertyCache::Ptr createPropertyCache(const QMetaObject *metaObject); + // These methods may be called from the loader thread static QQmlMetaObject rawMetaObjectForType(QMetaType metaType); static QQmlMetaObject metaObjectForType(QMetaType metaType); - static QQmlRefPointer propertyCacheForType(QMetaType metaType); - static QQmlRefPointer rawPropertyCacheForType(QMetaType metaType); - static QQmlRefPointer rawPropertyCacheForType( + static QQmlPropertyCache::ConstPtr propertyCacheForType(QMetaType metaType); + static QQmlPropertyCache::ConstPtr rawPropertyCacheForType(QMetaType metaType); + static QQmlPropertyCache::ConstPtr rawPropertyCacheForType( QMetaType metaType, QTypeRevision version); static void freeUnusedTypesAndCaches(); @@ -268,7 +285,7 @@ public: static QQmlValueType *valueType(QMetaType metaType); static const QMetaObject *metaObjectForValueType(QMetaType type); - static QQmlRefPointer findPropertyCacheInCompositeTypes(QMetaType t); + static QQmlPropertyCache::ConstPtr findPropertyCacheInCompositeTypes(QMetaType t); static void registerInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); static void unregisterInternalCompositeType(QV4::ExecutableCompilationUnit *compilationUnit); static QV4::ExecutableCompilationUnit *obtainExecutableCompilationUnit(QMetaType type); -- cgit v1.2.3