Fix a crash that was only showing up on Windows for some reason. Modifying a set...
authordooglus <dooglus@1f10aa63-cdf2-0310-b900-c93c546f37ac>
Sun, 3 Feb 2008 23:03:56 +0000 (23:03 +0000)
committerdooglus <dooglus@1f10aa63-cdf2-0310-b900-c93c546f37ac>
Sun, 3 Feb 2008 23:03:56 +0000 (23:03 +0000)
git-svn-id: http://svn.voria.com/code@1570 1f10aa63-cdf2-0310-b900-c93c546f37ac

synfig-core/trunk/src/synfig/canvas.cpp

index c51507a..8cf1f20 100644 (file)
@@ -90,17 +90,32 @@ Canvas::on_changed()
 
 Canvas::~Canvas()
 {
+       bool keep_going = true;
+
        // we were having a crash where pastecanvas layers were still
        // refering to a canvas after it had been destroyed;  this code
        // will stop the pastecanvas layers from refering to the canvas
        // before the canvas is destroyed
-       for (std::set<Node*>::iterator iter = parent_set.begin(); iter != parent_set.end(); iter++)
+
+       // the set_sub_canvas(0) ends up deleting the parent-child link,
+       // which modifies the set we're iterating through, invalidating
+       // the set iterator.  the outer while loop makes sure that we
+       // recreate the set iterator each time the set itself is modified
+       while (keep_going)
        {
-               Layer_PasteCanvas* paste_canvas = dynamic_cast<Layer_PasteCanvas*>(*iter);
-               if(paste_canvas)
-                       paste_canvas->set_sub_canvas(0);
-               else
-                       warning("destroyed canvas has a parent that is not a pastecanvas - please report if repeatable");
+               keep_going = false;             // only keep going if we find a pastecanvas parent to clear
+               for (std::set<Node*>::iterator iter = parent_set.begin(); iter != parent_set.end(); iter++)
+               {
+                       Layer_PasteCanvas* paste_canvas = dynamic_cast<Layer_PasteCanvas*>(*iter);
+                       if(paste_canvas)
+                       {
+                               paste_canvas->set_sub_canvas(0);
+                               keep_going = true;
+                               break;                  // out of the for loop to the while loop
+                       }
+                       else
+                               warning("destroyed canvas has a parent that is not a pastecanvas - please report if repeatable");
+               }
        }
 
        //if(is_inline() && parent_) assert(0);