From e0d6cd449822055148e1226eef03bd9b001150fc Mon Sep 17 00:00:00 2001 From: Andrei Golubev Date: Fri, 20 Nov 2020 10:44:44 +0100 Subject: Fix QML property cache leaks of delegate items The delegate items are destroyed through an event loop by a call to a deleteLater(). This, however, doesn't work when the application is in the process of exiting and the event loop is already closed (i.e. we're in a stack unwinding part that starts after app.exec()) Combat this situation by setting a parent of the to-be-deleted object to some QObject that will be destroyed e.g. QCoreApplication::instance() before the program finishes. As QObjects clean their children on destruction, this will make sure that we cleanup the previously leaking thing regardless of the event loop Added a test to check that delegates are destroyed (as a separate binary due to differences in main() function) Fixes: QTBUG-87228 Change-Id: I59066603b77497fe4fd8d051798c3e4b47c119f0 Reviewed-by: Fabian Kosmale (cherry picked from commit 3a5617dc45e281552b9c1f7a04f0561b8fa14d94) Reviewed-by: Qt Cherry-pick Bot --- src/qmlmodels/qqmldelegatemodel.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/qmlmodels') diff --git a/src/qmlmodels/qqmldelegatemodel.cpp b/src/qmlmodels/qqmldelegatemodel.cpp index 1a053e2e31..4f211aea53 100644 --- a/src/qmlmodels/qqmldelegatemodel.cpp +++ b/src/qmlmodels/qqmldelegatemodel.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQml module of the Qt Toolkit. @@ -2377,6 +2377,15 @@ void QQmlDelegateModelItem::destroyObject() data->ownContext = nullptr; data->context = nullptr; } + /* QTBUG-87228: when destroying object at the application exit, the deferred + * parent by setting it to QCoreApplication instance if it's nullptr, so + * deletion won't work. Not to leak memory, make sure our object has a that + * the parent claims the object at the end of the lifetime. When not at the + * application exit, normal event loop will handle the deferred deletion + * earlier. + */ + if (object->parent() == nullptr) + object->setParent(QCoreApplication::instance()); object->deleteLater(); if (attached) { -- cgit v1.2.3