aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Adams <chris.adams@jollamobile.com>2014-12-01 14:32:57 +1000
committerChristopher Adams <chris.adams@jollamobile.com>2014-12-04 04:04:20 +0100
commitb60bedf42ce7714180ced5597e8849b66a4d942b (patch)
treeb2c64e22e8d92594cad9044a98d8a37e6239231d
parent43c93a55e28a4655d8bc8d49a81b7802d7157244 (diff)
Fix QtQuick2 module unload support
This commit ensures that the value type providers installed by the QtQuick2 QML module during initialization are uninstalled when the plugin is unloaded. It also fixes a bug in the type compiler so that it now works with types from plugins which get unloaded and then reloaded. Task-number: QTBUG-43004 Change-Id: I4b3fb75aae65dfbc5de9c88701ed82514087ab7d Reviewed-by: Matthew Vogt <matthew.vogt@qinetic.com.au>
-rw-r--r--src/imports/qtquick2/plugin.cpp5
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp2
-rw-r--r--src/quick/qtquick2.cpp5
-rw-r--r--src/quick/qtquick2_p.h1
-rw-r--r--src/quick/qtquickglobal_p.h1
-rw-r--r--src/quick/util/qquickglobal.cpp7
-rw-r--r--tests/auto/qml/qqmlenginecleanup/data/testFile1.qml49
-rw-r--r--tests/auto/qml/qqmlenginecleanup/data/testFile2.qml46
-rw-r--r--tests/auto/qml/qqmlenginecleanup/data/testFile3.qml68
-rw-r--r--tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp45
10 files changed, 228 insertions, 1 deletions
diff --git a/src/imports/qtquick2/plugin.cpp b/src/imports/qtquick2/plugin.cpp
index d5096fc6e8..ad3db2290f 100644
--- a/src/imports/qtquick2/plugin.cpp
+++ b/src/imports/qtquick2/plugin.cpp
@@ -49,6 +49,11 @@ public:
Q_UNUSED(uri);
QQmlQtQuick2Module::defineModule();
}
+
+ ~QtQuick2Plugin()
+ {
+ QQmlQtQuick2Module::undefineModule();
+ }
};
//![class decl]
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 3a27a859fd..8edf4bbe7c 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -1389,7 +1389,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
if (!mo)
continue;
- static QQmlType *componentType = QQmlMetaType::qmlType(&QQmlComponent::staticMetaObject);
+ QQmlType *componentType = QQmlMetaType::qmlType(&QQmlComponent::staticMetaObject);
Q_ASSERT(componentType);
QmlIR::Object *syntheticComponent = pool->New<QmlIR::Object>();
diff --git a/src/quick/qtquick2.cpp b/src/quick/qtquick2.cpp
index 6acff85961..09784d161a 100644
--- a/src/quick/qtquick2.cpp
+++ b/src/quick/qtquick2.cpp
@@ -194,5 +194,10 @@ void QQmlQtQuick2Module::defineModule()
}
}
+void QQmlQtQuick2Module::undefineModule()
+{
+ QQuick_deinitializeProviders();
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/qtquick2_p.h b/src/quick/qtquick2_p.h
index 2847d5d3ff..8f415cbd02 100644
--- a/src/quick/qtquick2_p.h
+++ b/src/quick/qtquick2_p.h
@@ -42,6 +42,7 @@ class Q_QUICK_PRIVATE_EXPORT QQmlQtQuick2Module
{
public:
static void defineModule();
+ static void undefineModule();
};
QT_END_NAMESPACE
diff --git a/src/quick/qtquickglobal_p.h b/src/quick/qtquickglobal_p.h
index e2bf198b1c..7fe09da92e 100644
--- a/src/quick/qtquickglobal_p.h
+++ b/src/quick/qtquickglobal_p.h
@@ -54,6 +54,7 @@
QT_BEGIN_NAMESPACE
void QQuick_initializeProviders();
+void QQuick_deinitializeProviders();
Q_DECLARE_LOGGING_CATEGORY(DBG_TOUCH)
Q_DECLARE_LOGGING_CATEGORY(DBG_MOUSE)
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index 455e180dbe..139bae4038 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -982,4 +982,11 @@ void QQuick_initializeProviders()
QQml_setGuiProvider(getGuiProvider());
}
+void QQuick_deinitializeProviders()
+{
+ QQml_removeValueTypeProvider(getValueTypeProvider());
+ QQml_setColorProvider(0); // technically, another plugin may have overridden our providers
+ QQml_setGuiProvider(0); // but we cannot handle that case in a sane way.
+}
+
QT_END_NAMESPACE
diff --git a/tests/auto/qml/qqmlenginecleanup/data/testFile1.qml b/tests/auto/qml/qqmlenginecleanup/data/testFile1.qml
new file mode 100644
index 0000000000..3bd8e22ce4
--- /dev/null
+++ b/tests/auto/qml/qqmlenginecleanup/data/testFile1.qml
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ Item {
+ id: c1
+ }
+ property Item a: c1
+}
diff --git a/tests/auto/qml/qqmlenginecleanup/data/testFile2.qml b/tests/auto/qml/qqmlenginecleanup/data/testFile2.qml
new file mode 100644
index 0000000000..9a32114918
--- /dev/null
+++ b/tests/auto/qml/qqmlenginecleanup/data/testFile2.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ property variant a: Qt.rgba(0.3, 0.4, 0.5, 0.6)
+}
diff --git a/tests/auto/qml/qqmlenginecleanup/data/testFile3.qml b/tests/auto/qml/qqmlenginecleanup/data/testFile3.qml
new file mode 100644
index 0000000000..c55c355388
--- /dev/null
+++ b/tests/auto/qml/qqmlenginecleanup/data/testFile3.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ width: 320
+ height: 480
+
+ ListView {
+ anchors.fill: parent
+ model: simpleModel
+ delegate: Text {
+ text: name
+ }
+ }
+
+ ListModel {
+ id: simpleModel
+ ListElement {
+ name: "first"
+ }
+ ListElement {
+ name: "second"
+ }
+ ListElement {
+ name: "third"
+ }
+ }
+}
diff --git a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp
index fcc3e6a0a9..c8fae624a7 100644
--- a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp
+++ b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp
@@ -46,6 +46,7 @@ public:
private slots:
void test_qmlClearTypeRegistrations();
+ void test_valueTypeProviderModule(); // QTBUG-43004
};
void tst_qqmlenginecleanup::test_qmlClearTypeRegistrations()
@@ -85,6 +86,50 @@ void tst_qqmlenginecleanup::test_qmlClearTypeRegistrations()
delete component;
}
+static void cleanState(QQmlEngine **e)
+{
+ delete *e;
+ qmlClearTypeRegistrations();
+ *e = new QQmlEngine;
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::processEvents();
+}
+
+void tst_qqmlenginecleanup::test_valueTypeProviderModule()
+{
+ // this test ensures that a module which installs a value type
+ // provider can be reinitialized after multiple calls to
+ // qmlClearTypeRegistrations() without causing cycles in the
+ // value type provider list.
+ QQmlEngine *e = 0;
+ QUrl testFile1 = testFileUrl("testFile1.qml");
+ QUrl testFile2 = testFileUrl("testFile2.qml");
+ bool noCycles = false;
+ for (int i = 0; i < 20; ++i) {
+ cleanState(&e);
+ QQmlComponent c(e, this);
+ c.loadUrl(i % 2 == 0 ? testFile1 : testFile2); // this will hang if cycles exist.
+ }
+ delete e;
+ e = 0;
+ noCycles = true;
+ QVERIFY(noCycles);
+
+ // this test ensures that no crashes occur due to using
+ // a dangling QQmlType pointer in the type compiler
+ // which results from qmlClearTypeRegistrations()
+ QUrl testFile3 = testFileUrl("testFile3.qml");
+ bool noDangling = false;
+ for (int i = 0; i < 20; ++i) {
+ cleanState(&e);
+ QQmlComponent c(e, this);
+ c.loadUrl(i % 2 == 0 ? testFile1 : testFile3); // this will crash if dangling ptr exists.
+ }
+ delete e;
+ noDangling = true;
+ QVERIFY(noDangling);
+}
+
QTEST_MAIN(tst_qqmlenginecleanup)
#include "tst_qqmlenginecleanup.moc"