Delete nodes in the render thread at shutdown
authorAaron Kennedy <aaron.kennedy@nokia.com>
Wed, 9 Nov 2011 12:35:02 +0000 (12:35 +0000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 9 Nov 2011 14:18:09 +0000 (15:18 +0100)
This fixes a crash on OS X and possibly other platforms.

Change-Id: Ie8fc451b526d12d46133ef560c04e88c0b142b9a
Reviewed-by: Kim M. Kalland <kim.kalland@nokia.com>
src/declarative/items/qquickcanvas.cpp
src/declarative/items/qquickcanvas_p.h

index 86d44db..2f6821b 100644 (file)
@@ -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
 
index 610ebe7..702234d 100644 (file)
@@ -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<int, QQuickItem *> 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; }