# HG changeset patch # User David Bateman # Date 1227520847 -3600 # Node ID b6c3b16d4cfa9f47ab9cc76dba65809a74da902c # Parent fa9e6619fa9949a96e2cd393a53a97d4c46b37ac Check validitity of handles to delete before deleting them to avoid issues with callbacks deleting the handles as well diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -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 + + * 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 * load-path.cc (load_path::dir_info::update): Simplify previous diff --git a/src/graphics.cc b/src/graphics.cc --- a/src/graphics.cc +++ b/src/graphics.cc @@ -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");