changeset 8341:b6c3b16d4cfa

Check validitity of handles to delete before deleting them to avoid issues with callbacks deleting the handles as well
author David Bateman <dbateman@free.fr>
date Mon, 24 Nov 2008 11:00:47 +0100
parents fa9e6619fa99
children 39b9f7dfbf4a
files src/ChangeLog src/graphics.cc
diffstat 2 files changed, 46 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Mon Nov 24 10:57:53 2008 +0100
+++ b/src/ChangeLog	Mon Nov 24 11:00:47 2008 +0100
@@ -8,6 +8,12 @@
 	* DLD_FUNCTIONS/det.cc: Include only DET.h. Retrieve & matrix type &
 	store it after calculation if possible.
 
+2008-11-24  David Bateman  <dbateman@free.fr>
+
+	* graphics.cc (F__go_delete__): Check validity of handles before
+	deleting them to avoid issues with callback function also deleting
+	the handles.
+	
 2008-11-17  John W. Eaton  <jwe@octave.org>
 
 	* load-path.cc (load_path::dir_info::update): Simplify previous
--- a/src/graphics.cc	Mon Nov 24 10:57:53 2008 +0100
+++ b/src/graphics.cc	Mon Nov 24 11:00:47 2008 +0100
@@ -4582,44 +4582,56 @@
 
       if (! error_state)
 	{
+	  // Check is all the handles to delete are valid first
+	  // as callbacks might delete one of the handles we
+	  // later want to delete
 	  for (octave_idx_type i = 0; i < vals.numel (); i++)
 	    {
 	      h = gh_manager::lookup (vals.elem (i));
 
-	      if (h.ok ())
-		{
-		  graphics_object obj = gh_manager::get_object (h);
-
-		  // Don't do recursive deleting, due to callbacks
-		  if (! obj.get_properties ().is_beingdeleted ())
-		    {
-		      graphics_handle parent_h = obj.get_parent ();
-
-		      graphics_object parent_obj = 
-			gh_manager::get_object (parent_h);
-
-		      // NOTE: free the handle before removing it from its
-		      //       parent's children, such that the object's 
-		      //       state is correct when the deletefcn callback
-		      //       is executed
-
-		      gh_manager::free (h);
-
-		      // A callback function might have already deleted 
-		      // the parent
-		      if (parent_obj.valid_object ())
-			parent_obj.remove_child (h);
-
-		      Vdrawnow_requested = true;
-		    }
-		}
-	      else
+	      if (! h.ok ())
 		{
 		  error ("delete: invalid graphics object (= %g)", 
 			 vals.elem (i));
 		  break;
 		}
 	    }
+
+	  if (! error_state)
+	    {
+	      for (octave_idx_type i = 0; i < vals.numel (); i++)
+		{
+		  h = gh_manager::lookup (vals.elem (i));
+
+		  if (h.ok ())
+		    {
+		      graphics_object obj = gh_manager::get_object (h);
+
+		      // Don't do recursive deleting, due to callbacks
+		      if (! obj.get_properties ().is_beingdeleted ())
+			{
+			  graphics_handle parent_h = obj.get_parent ();
+
+			  graphics_object parent_obj = 
+			    gh_manager::get_object (parent_h);
+
+			  // NOTE: free the handle before removing it from its
+			  //       parent's children, such that the object's 
+			  //       state is correct when the deletefcn callback
+			  //       is executed
+
+			  gh_manager::free (h);
+
+			  // A callback function might have already deleted 
+			  // the parent
+			  if (parent_obj.valid_object ())
+			    parent_obj.remove_child (h);
+
+			  Vdrawnow_requested = true;
+			}
+		    }
+		}
+	    }
 	}
       else
 	error ("delete: invalid graphics object");