changeset 29014:df307ee1fb30 stable

Don't rely on graphics_objects destructor being executed synchronously (bug #53513). * graphics.in.h, graphics.cc (base_properties::update_beingdeleted): New virtual method, empty by default. (base_properties::set_beingdeleted): Call update_beingdeleted. (uicontextmenu::~uicontextmenu): Use a default destructor. (uicontextmenu::properties::update_beingdeleted): Overload to clear uicontextmenu properties of dependent objects.
author Pantxo Diribarne <pantxo.diribarne@gmail.com>
date Sun, 25 Oct 2020 20:11:11 +0100
parents 1684b2366200
children f2cb828493f1 2e1f9d07f0ab
files libinterp/corefcn/graphics.cc libinterp/corefcn/graphics.in.h
diffstat 2 files changed, 26 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/graphics.cc	Fri Oct 30 14:05:26 2020 -0700
+++ b/libinterp/corefcn/graphics.cc	Sun Oct 25 20:11:11 2020 +0100
@@ -10782,21 +10782,25 @@
 
 // ---------------------------------------------------------------------
 
-uicontextmenu::~uicontextmenu (void)
-{
-  std::list<graphics_handle> lst = xproperties.get_dependent_obj_list ();
-  std::list<graphics_handle>::const_iterator it;
-
-  gh_manager& gh_mgr
-    = octave::__get_gh_manager__ ("uicontextmenu::~uicontextmenu");
-
-  for (it = lst.begin (); it != lst.end (); it++)
-    {
-      graphics_object go = gh_mgr.get_object (*it);
-
-      if (go.valid_object ()
-          && go.get ("uicontextmenu") == xproperties.get___myhandle__ ())
-        go.set ("uicontextmenu", Matrix ());
+void
+uicontextmenu::properties::update_beingdeleted (void)
+{
+  // Clear the uicontextmenu property of dependent objects
+  if (beingdeleted.is ("on"))
+    {
+      gh_manager& gh_mgr
+        = octave::__get_gh_manager__ ("uicontextmenu::properties::update_beingdeleted");
+
+      std::list<graphics_handle> lst = get_dependent_obj_list ();
+
+      for (auto& hobj : lst)
+        {
+          graphics_object go = gh_mgr.get_object (hobj);
+
+          if (go.valid_object ()
+              && go.get ("uicontextmenu") == get___myhandle__ ())
+            go.set ("uicontextmenu", Matrix ());
+        }
     }
 }
 
--- a/libinterp/corefcn/graphics.in.h	Fri Oct 30 14:05:26 2020 -0700
+++ b/libinterp/corefcn/graphics.in.h	Sun Oct 25 20:11:11 2020 +0100
@@ -2282,6 +2282,7 @@
   void set_beingdeleted (const octave_value& val)
   {
     beingdeleted.set (val, true, false);
+    update_beingdeleted ();
   }
 
   void set_tag (const octave_value& val) { tag = val; }
@@ -2402,6 +2403,8 @@
     graphics_handle __myhandle__ fhrs , mh
   END_PROPERTIES
 
+  virtual void update_beingdeleted (void) { };
+
   virtual void update_handlevisibility (void);
 
   virtual void update_visible (void) { };
@@ -5465,6 +5468,9 @@
   private:
     // List of objects that might depend on this uicontextmenu object
     std::list<graphics_handle> dependent_obj_list;
+
+    void update_beingdeleted (void);
+
   };
 
 private:
@@ -5475,7 +5481,7 @@
     : base_graphics_object (), xproperties (mh, p)
   { }
 
-  ~uicontextmenu (void);
+  ~uicontextmenu (void) = default;
 
   base_properties& get_properties (void) { return xproperties; }