diff options
author | Michael Brasser <mbrasser@ford.com> | 2018-01-08 13:33:27 -0600 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-10-26 05:20:41 +0000 |
commit | 475c74a9926efcd968572563e678988e53804603 (patch) | |
tree | 57675cdf22c34a098f82ecb54baf01be5dcbd810 /tests | |
parent | 33d85e20037e83d10b8ce66f8745f00d84baccd8 (diff) |
Hold internal reference to incubator object while incubating
Task-number: QTBUG-53111
Change-Id: Ifaef6a855914d79155f8028b0de7ccca3c9a00f5
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/qml/qqmlincubator/data/garbageCollection.qml | 19 | ||||
-rw-r--r-- | tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp | 30 |
2 files changed, 49 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlincubator/data/garbageCollection.qml b/tests/auto/qml/qqmlincubator/data/garbageCollection.qml new file mode 100644 index 0000000000..6866a02a00 --- /dev/null +++ b/tests/auto/qml/qqmlincubator/data/garbageCollection.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +QtObject { + id: root + + property var incubator + + function getAndClearIncubator() { + var result = incubator + incubator = null + return result + } + + Component.onCompleted: { + var c = Qt.createComponent("statusChanged.qml"); // use existing simple type for convenience + var incubator = c.incubateObject(root); + incubator.onStatusChanged = function(status) { if (status === 1) root.incubator = incubator } + } +} diff --git a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp index 8f0e04e12e..8e25079703 100644 --- a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp +++ b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp @@ -39,6 +39,7 @@ #include <QQmlComponent> #include <QQmlIncubator> #include "../../shared/util.h" +#include <private/qjsvalue_p.h> #include <private/qqmlincubator_p.h> #include <private/qqmlobjectcreator_p.h> @@ -68,6 +69,7 @@ private slots: void chainedAsynchronousClear(); void selfDelete(); void contextDelete(); + void garbageCollection(); private: QQmlIncubationController controller; @@ -1144,6 +1146,34 @@ void tst_qqmlincubator::contextDelete() } } +// QTBUG-53111 +void tst_qqmlincubator::garbageCollection() +{ + QQmlComponent component(&engine, testFileUrl("garbageCollection.qml")); + QScopedPointer<QObject> obj(component.create()); + + engine.collectGarbage(); + + bool b = true; + controller.incubateWhile(&b); + + // verify incubation completed (the incubator was not prematurely collected) + QVariant incubatorVariant; + QMetaObject::invokeMethod(obj.data(), "getAndClearIncubator", Q_RETURN_ARG(QVariant, incubatorVariant)); + QJSValue strongRef = incubatorVariant.value<QJSValue>(); + QVERIFY(!strongRef.isNull() && !strongRef.isUndefined()); + + // turn the last strong reference to the incubator into a weak one and collect + QV4::WeakValue weakIncubatorRef; + weakIncubatorRef.set(QQmlEnginePrivate::getV4Engine(&engine), *QJSValuePrivate::getValue(&strongRef)); + strongRef = QJSValue(); + incubatorVariant.clear(); + + // verify incubator is correctly collected now that incubation is complete and all references are gone + engine.collectGarbage(); + QVERIFY(weakIncubatorRef.isNullOrUndefined()); +} + QTEST_MAIN(tst_qqmlincubator) #include "tst_qqmlincubator.moc" |