From 0ecadd9530626e981fa994cee1d505d32249f503 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 20 Mar 2012 11:58:09 +1000 Subject: [PATCH] Loader could leak qml contexts if interrupted If Loader was either destroyed, or its source changed while it was incubating the itemContext could be leaked. Change-Id: I5b749062552954d92bf2851250f942b20ebbfe68 Reviewed-by: Andrew den Exter --- src/quick/items/qquickloader.cpp | 12 ++++++++++++ tests/auto/quick/qquickloader/tst_qquickloader.cpp | 6 ++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index 59cb37c15d..f41ba44943 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -61,6 +61,8 @@ QQuickLoaderPrivate::QQuickLoaderPrivate() QQuickLoaderPrivate::~QQuickLoaderPrivate() { + delete itemContext; + itemContext = 0; delete incubator; disposeInitialPropertyValues(); } @@ -79,12 +81,21 @@ void QQuickLoaderPrivate::itemGeometryChanged(QQuickItem *resizeItem, const QRec void QQuickLoaderPrivate::clear() { + Q_Q(QQuickLoader); disposeInitialPropertyValues(); if (incubator) incubator->clear(); + delete itemContext; + itemContext = 0; + if (loadingFromSource && component) { + // disconnect since we deleteLater + QObject::disconnect(component, SIGNAL(statusChanged(QQmlComponent::Status)), + q, SLOT(_q_sourceLoaded())); + QObject::disconnect(component, SIGNAL(progressChanged(qreal)), + q, SIGNAL(progressChanged())); component->deleteLater(); component = 0; } @@ -545,6 +556,7 @@ void QQuickLoaderPrivate::setInitialState(QObject *obj) QQml_setParent_noEvent(itemContext, obj); QQml_setParent_noEvent(item, q); item->setParentItem(q); + itemContext = 0; } if (initialPropertyValues.IsEmpty()) diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp index bdf47fa9e9..01781f7b54 100644 --- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp +++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp @@ -929,7 +929,7 @@ void tst_QQuickLoader::asynchronous_clear() QVERIFY(!loader->item()); QCOMPARE(loader->status(), QQuickLoader::Loading); - QCOMPARE(engine.incubationController()->incubatingObjectCount(), 1); + QTRY_COMPARE(engine.incubationController()->incubatingObjectCount(), 1); // clear before component created root->setProperty("comp", ""); @@ -942,7 +942,7 @@ void tst_QQuickLoader::asynchronous_clear() QCOMPARE(static_cast(loader)->childItems().count(), 0); // check loading component - root->setProperty("comp", "Rect120x60.qml"); + root->setProperty("comp", "BigComponent.qml"); QMetaObject::invokeMethod(root, "loadComponent"); QVERIFY(!loader->item()); @@ -953,6 +953,8 @@ void tst_QQuickLoader::asynchronous_clear() QCOMPARE(loader->progress(), 1.0); QCOMPARE(loader->status(), QQuickLoader::Ready); QCOMPARE(static_cast(loader)->childItems().count(), 1); + + delete root; } void tst_QQuickLoader::simultaneousSyncAsync()