From 83fdcbf3be0ddbbee1fd2c8c9ff1a4e3c707e3f0 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 18 Feb 2020 15:16:54 +0100 Subject: QQmlTableInstanceModel: Fix refcounting of metatypes The reusable items pool should only hold unreferenced objects. Therefore, we can immediately delete them when draining. release() is not suitable here because it unconditionally decreases and therefore underflows the refcount. Furthermore, the metatype is also refcounted, which means we should keep it in a QQmlRefCounter in order to not leak references. Task-number: QTBUG-82000 Change-Id: Iefdaaecc34342eb2e3b1e5a3281f2e46ac472347 Reviewed-by: Joni Poikelin Reviewed-by: Simon Hausmann --- src/qmlmodels/qqmltableinstancemodel.cpp | 16 +++++++++++++--- src/qmlmodels/qqmltableinstancemodel_p.h | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'src/qmlmodels') diff --git a/src/qmlmodels/qqmltableinstancemodel.cpp b/src/qmlmodels/qqmltableinstancemodel.cpp index fb2f7ee98b..9800eb8c72 100644 --- a/src/qmlmodels/qqmltableinstancemodel.cpp +++ b/src/qmlmodels/qqmltableinstancemodel.cpp @@ -78,7 +78,10 @@ void QQmlTableInstanceModel::deleteModelItemLater(QQmlDelegateModelItem *modelIt QQmlTableInstanceModel::QQmlTableInstanceModel(QQmlContext *qmlContext, QObject *parent) : QQmlInstanceModel(*(new QObjectPrivate()), parent) , m_qmlContext(qmlContext) - , m_metaType(new QQmlDelegateModelItemMetaType(m_qmlContext->engine()->handle(), nullptr, QStringList())) + , m_metaType( + new QQmlDelegateModelItemMetaType(m_qmlContext->engine()->handle(), nullptr, + QStringList()), + QQmlRefPointer::Adopt) { } @@ -149,7 +152,7 @@ QQmlDelegateModelItem *QQmlTableInstanceModel::resolveModelItem(int index) } // Create a new item from scratch - modelItem = m_adaptorModel.createItem(m_metaType, index); + modelItem = m_adaptorModel.createItem(m_metaType.data(), index); if (modelItem) { modelItem->delegate = delegate; m_modelItems.insert(index, modelItem); @@ -333,7 +336,14 @@ void QQmlTableInstanceModel::drainReusableItemsPool(int maxPoolTime) ++it; } else { it = m_reusableItemsPool.erase(it); - release(modelItem->object, NotReusable); + + Q_ASSERT(!modelItem->incubationTask); + Q_ASSERT(!modelItem->isObjectReferenced()); + Q_ASSERT(!modelItem->isReferenced()); + Q_ASSERT(modelItem->object); + emit destroyingItem(modelItem->object); + delete modelItem->object; + delete modelItem; } } } diff --git a/src/qmlmodels/qqmltableinstancemodel_p.h b/src/qmlmodels/qqmltableinstancemodel_p.h index 1ea5ee7401..fd5968d872 100644 --- a/src/qmlmodels/qqmltableinstancemodel_p.h +++ b/src/qmlmodels/qqmltableinstancemodel_p.h @@ -142,7 +142,7 @@ private: QQmlAbstractDelegateComponent *m_delegateChooser = nullptr; QQmlComponent *m_delegate = nullptr; QPointer m_qmlContext; - QQmlDelegateModelItemMetaType *m_metaType; + QQmlRefPointer m_metaType; QHash m_modelItems; QList m_reusableItemsPool; -- cgit v1.2.3