diff options
author | Alan Alpert <aalpert@rim.com> | 2013-01-24 14:07:29 -0800 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-05-07 19:41:28 +0200 |
commit | 9b5a55101d7c519446c1cf3706a235dea81ad4de (patch) | |
tree | 8f7201f04f8e593c8e00fd4d293d2d28e1a655ab /src/qml | |
parent | 223313479bf8ec80158ba0f6cba4dd5e74d92718 (diff) |
Add qmlClearRegisteredTypes Function
Registered types are stored in a global static variable, not on an
engine instance. For applications managing multiple engines over their
lifetime, there needs to be a way to clear the existing types so they
can register new ones and avoid memory leaks.
Task-Number: QTBUG-28572
Change-Id: Ic70a4dd1e29d99399b21fb42eaf10d4a52bf2adf
Reviewed-by: Christopher Adams <chris.adams@jollamobile.com>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/doc/src/qmlfunctions.qdoc | 14 | ||||
-rw-r--r-- | src/qml/qml/qqml.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine_p.h | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlimport.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlimport_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 24 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype_p.h | 2 |
8 files changed, 58 insertions, 3 deletions
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc index 976403adea..386f9f49df 100644 --- a/src/qml/doc/src/qmlfunctions.qdoc +++ b/src/qml/doc/src/qmlfunctions.qdoc @@ -47,6 +47,20 @@ #include <QtQml> to use this macro. */ +/*! + \fn void qmlClearTypeRegistrations() + \relates QQmlEngine + + Clears all stored type registrations, such as those produced with \l qmlRegisterType. + + Do not call this function while a QQmlEngine exists or behavior will be undefined. + Any existing QQmlEngines must be deleted before calling this function. This function + only affects the application global cache. Delete the QQmlEngine to clear all cached + data relating to that engine. + + #include <QtQml> to use this method. +*/ + /*! \fn int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index 7e6e0d1d36..f04cf7d6fa 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -102,6 +102,8 @@ class QQmlPropertyValueInterceptor; listName[listLen+nameLen] = '>'; \ listName[listLen+nameLen+1] = '\0'; +void Q_QML_EXPORT qmlClearTypeRegistrations(); + template<typename T> int qmlRegisterType() { diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 9d2ad8c4c3..34ebe0a9e2 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -722,17 +722,17 @@ void QQmlData::flushPendingBindingImpl(int coreIndex) } } +bool QQmlEnginePrivate::baseModulesUninitialized = true; void QQmlEnginePrivate::init() { Q_Q(QQmlEngine); - static bool firstTime = true; - if (firstTime) { + if (baseModulesUninitialized) { qmlRegisterType<QQmlComponent>("QML", 1, 0, "Component"); // required for the Compiler. registerBaseTypes("QtQml", 2, 0); // import which provides language building blocks. QQmlData::init(); - firstTime = false; + baseModulesUninitialized = false; } qRegisterMetaType<QVariant>(); diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index b745d6a963..0d852c1c1b 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -125,6 +125,9 @@ public: ~QQmlEnginePrivate(); void init(); + // No mutex protecting baseModulesUninitialized, because use outside QQmlEngine + // is just qmlClearTypeRegistrations (which can't be called while an engine exists) + static bool baseModulesUninitialized; class PropertyCapture { public: diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index f793ca9604..2fbb614605 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -163,6 +163,14 @@ QQmlType *getTypeForUrl(const QString &urlString, const QHashedStringRef& typeNa typedef QMap<QString, QString> StringStringMap; Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri +void qmlClearEnginePlugins() +{ + foreach (const QString &s, qmlEnginePluginsWithRegisteredTypes()->values()) { + QPluginLoader loader(s); + loader.unload(); // ### Always returns false, worth doing? + } + qmlEnginePluginsWithRegisteredTypes()->clear(); +} class QQmlImportNamespace { diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h index 140ca6695e..06b50c09e9 100644 --- a/src/qml/qml/qqmlimport_p.h +++ b/src/qml/qml/qqmlimport_p.h @@ -182,6 +182,8 @@ private: QQmlEngine *engine; }; +void qmlClearEnginePlugins();// For internal use by qmlClearRegisteredProperties + QT_END_NAMESPACE #endif // QQMLIMPORT_P_H diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 0f3a27aeff..b29df4d252 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -46,6 +46,7 @@ #include <private/qqmlcustomparser_p.h> #include <private/qqmlguard_p.h> #include <private/qhashedstring_p.h> +#include <private/qqmlimport_p.h> #include <QtCore/qdebug.h> #include <QtCore/qstringlist.h> @@ -1068,6 +1069,29 @@ QQmlType *QQmlTypeModuleVersion::type(const QHashedV8String &name) const else return 0; } +void qmlClearTypeRegistrations() // Declared in qqml.h +{ + //Only cleans global static, assumed no running engine + QWriteLocker lock(metaTypeDataLock()); + QQmlMetaTypeData *data = metaTypeData(); + + for (int i = 0; i < data->types.count(); ++i) + delete data->types.at(i); + + QQmlMetaTypeData::TypeModules::const_iterator i = data->uriToModule.constBegin(); + for (; i != data->uriToModule.constEnd(); ++i) + delete *i; + + data->types.clear(); + data->idToType.clear(); + data->nameToType.clear(); + data->urlToType.clear(); + data->metaObjectToType.clear(); + data->uriToModule.clear(); + + QQmlEnginePrivate::baseModulesUninitialized = true; //So the engine re-registers its types + qmlClearEnginePlugins(); +} int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent) { diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 497afffb5d..12901e8c58 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -231,6 +231,7 @@ private: friend int registerSingletonType(const QQmlPrivate::RegisterSingletonType &); friend int registerInterface(const QQmlPrivate::RegisterInterface &); friend int registerCompositeType(const QQmlPrivate::RegisterCompositeType &); + friend void qmlClearTypeRegistrations(); QQmlType(int, const QQmlPrivate::RegisterInterface &); QQmlType(int, const QString &, const QQmlPrivate::RegisterSingletonType &); QQmlType(int, const QString &, const QQmlPrivate::RegisterType &); @@ -259,6 +260,7 @@ private: //Used by register functions and creates the QQmlTypeModule for them friend void addTypeToData(QQmlType* type, QQmlMetaTypeData *data); friend struct QQmlMetaTypeData; + friend void qmlClearTypeRegistrations(); QQmlTypeModule(); ~QQmlTypeModule(); |