aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorAlbert Astals Cid <albert.astals@canonical.com>2013-04-30 14:03:03 -0700
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-05-03 19:11:18 +0200
commit9d6cd72353e4862592c016951810abf9a7ab8079 (patch)
tree76cf626c81756ff5e11694b2b636b7d8f67c765b /src/qml
parente1a8762e9c39133cb3d1d9c2cdf51003f75d6c05 (diff)
Fix crash in QQmlDelegateModel
It can happen that when the QQmlDelegateModel goes away some of the QQmlDelegateModelItem from d->m_cache are still incubating, this means that isReferenced() will return true and we will not delete them. This also means that when these QQDMIncubationTask finish they may end up calling QQDMIncubationTask::statusChanged which will try to access the delegate model that is already gone. This commit makes sure we set vdm to 0 in these orphaned QQDMIncubationTask so in QQDMIncubationTask::statusChanged we know no one cares about us anymore and don't reference the already gone delegate model Task-number: QTBUG-30928 Change-Id: Ief6176cec151d861dad09ca2498ca27e17ee6385 Reviewed-by: Andrew den Exter <andrew.den.exter@qinetic.com.au>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 16572c44dd..5e36be1eca 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -230,6 +230,8 @@ QQmlDelegateModel::~QQmlDelegateModel()
cacheItem->objectRef = 0;
if (!cacheItem->isReferenced())
delete cacheItem;
+ else if (cacheItem->incubationTask)
+ cacheItem->incubationTask->vdm = 0;
}
}
@@ -780,7 +782,21 @@ void QQmlDelegateModelPrivate::emitDestroyingPackage(QQuickPackage *package)
void QQDMIncubationTask::statusChanged(Status status)
{
- vdm->incubatorStatusChanged(this, status);
+ if (vdm) {
+ vdm->incubatorStatusChanged(this, status);
+ } else if (status == QQmlIncubator::Ready || status == QQmlIncubator::Error) {
+ Q_ASSERT(incubating);
+ // The model was deleted from under our feet, cleanup ourselves
+ if (incubating->object) {
+ delete incubating->object;
+
+ incubating->object = 0;
+ incubating->contextData->destroy();
+ incubating->contextData = 0;
+ }
+ incubating->scriptRef = 0;
+ incubating->deleteLater();
+ }
}
void QQmlDelegateModelPrivate::releaseIncubator(QQDMIncubationTask *incubationTask)
@@ -1766,8 +1782,12 @@ QQmlDelegateModelItem::~QQmlDelegateModelItem()
Q_ASSERT(objectRef == 0);
Q_ASSERT(!object);
- if (incubationTask && metaType->model)
- QQmlDelegateModelPrivate::get(metaType->model)->releaseIncubator(incubationTask);
+ if (incubationTask) {
+ if (metaType->model)
+ QQmlDelegateModelPrivate::get(metaType->model)->releaseIncubator(incubationTask);
+ else
+ delete incubationTask;
+ }
metaType->release();