diff options
11 files changed, 186 insertions, 11 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 573288b77f..aac76b6055 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -1648,7 +1648,14 @@ void qmlClearTypeRegistrations() // Declared in qqml.h #endif } -static int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent) +static void unregisterAutoParentFunction(const QQmlPrivate::AutoParentFunction &function) +{ + QMutexLocker lock(metaTypeDataLock()); + QQmlMetaTypeData *data = metaTypeData(); + data->parentFunctions.removeOne(function); +} + +static int registerAutoParentFunction(const QQmlPrivate::RegisterAutoParent &autoparent) { QMutexLocker lock(metaTypeDataLock()); QQmlMetaTypeData *data = metaTypeData(); @@ -1957,6 +1964,26 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) return dtype.index(); } +void QQmlPrivate::qmlunregister(RegistrationType type, quintptr data) +{ + switch (type) { + case AutoParentRegistration: + unregisterAutoParentFunction(reinterpret_cast<AutoParentFunction>(data)); + break; + case QmlUnitCacheHookRegistration: + QQmlMetaType::removeCachedUnitLookupFunction( + reinterpret_cast<QmlUnitCacheLookupFunction>(data)); + break; + case TypeRegistration: + case InterfaceRegistration: + case SingletonRegistration: + case CompositeRegistration: + case CompositeSingletonRegistration: + qmlUnregisterType(data); + break; + } +} + //From qqml.h bool qmlProtectModule(const char *uri, int majVersion) { diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index ae84803648..8a45de9f76 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -318,6 +318,7 @@ namespace QQmlPrivate }; int Q_QML_EXPORT qmlregister(RegistrationType, void *); + void Q_QML_EXPORT qmlunregister(RegistrationType, quintptr); } QT_END_NAMESPACE diff --git a/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/CustomModule.pro b/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/CustomModule.pro new file mode 100644 index 0000000000..3366ddc165 --- /dev/null +++ b/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/CustomModule.pro @@ -0,0 +1,13 @@ +TEMPLATE = lib +TARGET = CustomModule +QT += quick qml + +CONFIG += qtquickcompiler +SOURCES += moduleplugin.cpp +RESOURCES += moduleplugin.qrc + +DESTDIR = ../CustomModule + +IMPORT_FILES = qmldir + +include (../../../shared/imports.pri) diff --git a/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/ModuleType.qml b/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/ModuleType.qml new file mode 100644 index 0000000000..ed154e3aa9 --- /dev/null +++ b/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/ModuleType.qml @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQml 2.12 + +QtObject { + objectName: "moduleType" +} diff --git a/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/moduleplugin.cpp b/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/moduleplugin.cpp new file mode 100644 index 0000000000..048250c730 --- /dev/null +++ b/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/moduleplugin.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtQml/qqmlextensionplugin.h> +#include <QtQml/qqmlengine.h> + +QT_BEGIN_NAMESPACE + +class ModulePlugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) + +public: + ModulePlugin(QObject *parent = nullptr) : QQmlExtensionPlugin(parent) {} + void registerTypes(const char *uri) override; +}; + +void ModulePlugin::registerTypes(const char *uri) +{ + qmlRegisterModule(uri, 1, 0); + qmlRegisterType(QUrl("qrc:/ModuleType.qml"), uri, 1, 0, "ModuleType"); +} + +QT_END_NAMESPACE + +#include "moduleplugin.moc" diff --git a/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/moduleplugin.qrc b/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/moduleplugin.qrc new file mode 100644 index 0000000000..c8f7dea691 --- /dev/null +++ b/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/moduleplugin.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>ModuleType.qml</file> + </qresource> +</RCC> diff --git a/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/qmldir b/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/qmldir new file mode 100644 index 0000000000..f421ba44dc --- /dev/null +++ b/tests/auto/qml/qqmlenginecleanup/CustomModuleImport/qmldir @@ -0,0 +1,3 @@ +module CustomModule +plugin CustomModule +classname ModulePlugin diff --git a/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro b/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro index 90508609a8..34c49a5c0e 100644 --- a/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro +++ b/tests/auto/qml/qqmlenginecleanup/qqmlenginecleanup.pro @@ -1,9 +1,2 @@ -CONFIG += testcase -TARGET = tst_qqmlenginecleanup -macx:CONFIG -= app_bundle - -include (../../shared/util.pri) - -SOURCES += tst_qqmlenginecleanup.cpp - -QT += testlib qml qml-private +TEMPLATE = subdirs +SUBDIRS += tst_qqmlenginecleanup.pro CustomModuleImport/CustomModule.pro diff --git a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp index b9cede6d13..690db30838 100644 --- a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp +++ b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp @@ -44,6 +44,7 @@ public: private slots: void test_qmlClearTypeRegistrations(); void test_valueTypeProviderModule(); // QTBUG-43004 + void test_customModuleCleanup(); }; // A wrapper around QQmlComponent to ensure the temporary reference counts @@ -168,6 +169,23 @@ void tst_qqmlenginecleanup::test_valueTypeProviderModule() QVERIFY(noDangling); } +void tst_qqmlenginecleanup::test_customModuleCleanup() +{ + for (int i = 0; i < 5; ++i) { + qmlClearTypeRegistrations(); + + QQmlEngine engine; + engine.addImportPath(QT_TESTCASE_BUILDDIR); + + QQmlComponent component(&engine); + component.setData("import CustomModule 1.0\nModuleType {}", QUrl()); + QCOMPARE(component.status(), QQmlComponent::Ready); + + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + } +} + QTEST_MAIN(tst_qqmlenginecleanup) #include "tst_qqmlenginecleanup.moc" diff --git a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.pro b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.pro new file mode 100644 index 0000000000..90508609a8 --- /dev/null +++ b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.pro @@ -0,0 +1,9 @@ +CONFIG += testcase +TARGET = tst_qqmlenginecleanup +macx:CONFIG -= app_bundle + +include (../../shared/util.pri) + +SOURCES += tst_qqmlenginecleanup.cpp + +QT += testlib qml qml-private diff --git a/tools/qmlcachegen/generateloader.cpp b/tools/qmlcachegen/generateloader.cpp index 68aacf78ce..5638b311c2 100644 --- a/tools/qmlcachegen/generateloader.cpp +++ b/tools/qmlcachegen/generateloader.cpp @@ -357,6 +357,7 @@ bool generateLoader(const QStringList &compiledFiles, const QString &outputFileN stream << "struct Registry {\n"; stream << " Registry();\n"; + stream << " ~Registry();\n"; stream << " QHash<QString, const QQmlPrivate::CachedQmlUnit*> resourcePathToCachedUnit;\n"; stream << " static const QQmlPrivate::CachedQmlUnit *lookupCachedUnit(const QUrl &url);\n"; stream << "};\n\n"; @@ -379,7 +380,11 @@ bool generateLoader(const QStringList &compiledFiles, const QString &outputFileN if (!resourceRegisterCall.isEmpty()) stream << resourceRegisterCall; - stream << "}\n"; + stream << "}\n\n"; + stream << "Registry::~Registry() {\n"; + stream << " QQmlPrivate::qmlunregister(QQmlPrivate::QmlUnitCacheHookRegistration, quintptr(&lookupCachedUnit));\n"; + stream << "}\n\n"; + stream << "const QQmlPrivate::CachedQmlUnit *Registry::lookupCachedUnit(const QUrl &url) {\n"; stream << " if (url.scheme() != QLatin1String(\"qrc\"))\n"; stream << " return nullptr;\n"; |