From 39b7c020a38a2a0dadc72c2f841fdb8f322f8588 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 9 Nov 2011 12:35:02 +0000 Subject: [PATCH] Delete nodes in the render thread at shutdown This fixes a crash on OS X and possibly other platforms. Change-Id: Ie8fc451b526d12d46133ef560c04e88c0b142b9a Reviewed-by: Kim M. Kalland --- src/declarative/items/qquickcanvas.cpp | 29 +++++++++++++++++++++++++++++ src/declarative/items/qquickcanvas_p.h | 4 ++++ 2 files changed, 33 insertions(+) diff --git a/src/declarative/items/qquickcanvas.cpp b/src/declarative/items/qquickcanvas.cpp index 86d44db..2f6821b 100644 --- a/src/declarative/items/qquickcanvas.cpp +++ b/src/declarative/items/qquickcanvas.cpp @@ -1633,6 +1633,30 @@ void QQuickCanvasPrivate::cleanupNodes() cleanupNodeList.clear(); } +void QQuickCanvasPrivate::cleanupNodesOnShutdown(QQuickItem *item) +{ + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + if (p->itemNodeInstance) { + delete p->itemNodeInstance; + p->itemNodeInstance = 0; + p->opacityNode = 0; + p->clipNode = 0; + p->groupNode = 0; + p->paintNode = 0; + } + + for (int ii = 0; ii < p->childItems.count(); ++ii) + cleanupNodesOnShutdown(p->childItems.at(ii)); +} + +// This must be called from the render thread, with the main thread frozen +void QQuickCanvasPrivate::cleanupNodesOnShutdown() +{ + cleanupNodes(); + + cleanupNodesOnShutdown(rootItem); +} + void QQuickCanvasPrivate::updateDirtyNodes() { #ifdef DIRTY_DEBUG @@ -2137,6 +2161,11 @@ void QQuickCanvasRenderThread::run() } #ifdef THREAD_DEBUG + printf(" RenderThread: deleting all outstanding nodes\n"); +#endif + cleanupNodesOnShutdown(); + +#ifdef THREAD_DEBUG printf(" RenderThread: render loop exited... Good Night!\n"); #endif diff --git a/src/declarative/items/qquickcanvas_p.h b/src/declarative/items/qquickcanvas_p.h index 610ebe7..702234d 100644 --- a/src/declarative/items/qquickcanvas_p.h +++ b/src/declarative/items/qquickcanvas_p.h @@ -152,6 +152,7 @@ public: void updateDirtyNodes(); void cleanupNodes(); + void cleanupNodesOnShutdown(); bool updateEffectiveOpacity(QQuickItem *); void updateEffectiveOpacityRoot(QQuickItem *, qreal); void updateDirtyNode(QQuickItem *); @@ -171,6 +172,8 @@ public: QHash itemForTouchPointId; mutable QQuickCanvasIncubationController *incubationController; +private: + static void cleanupNodesOnShutdown(QQuickItem *); }; class QQuickCanvasRenderLoop @@ -205,6 +208,7 @@ public: protected: void initializeSceneGraph() { d->initializeSceneGraph(); } void syncSceneGraph() { d->syncSceneGraph(); } + void cleanupNodesOnShutdown() { d->cleanupNodesOnShutdown(); } void renderSceneGraph(const QSize &size) { d->renderSceneGraph(size); } void polishItems() { d->polishItems(); } QAnimationDriver *animationDriver() const { return d->animationDriver; } -- 2.7.4