changeset 27689:4f32af6abd4b

don't use static variable for list of interpreter atexit functions * interpreter.h, interpreter.cc (atexit_functions): Delete static variable. (interpreter::m_atexit_fcns): New member variable. Replace all uses of old atexit_functions list with this variable. (Fatexit): Call new member functions instead of static functions. (interpreter::execute_atexit_fcns): New function. (interpreter::cleanup): Call execute_atexit_fcns instead of doing that job directly here. (interpreter::add_atexit_fcn, interpreter::remove_atexit_fcn): New member functions. (interpreter::add_atexit_function, interpreter::remove_atexit_function): Deprecate static functions. Call new member functions.
author John W. Eaton <jwe@octave.org>
date Thu, 14 Nov 2019 15:18:15 -0500
parents 7e6836784575
children c81139d8dcc3
files libinterp/corefcn/interpreter.cc libinterp/corefcn/interpreter.h
diffstat 2 files changed, 52 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/interpreter.cc	Thu Nov 14 11:14:25 2019 -0800
+++ b/libinterp/corefcn/interpreter.cc	Thu Nov 14 15:18:15 2019 -0500
@@ -279,10 +279,10 @@
   octave_value_list retval;
 
   if (add_mode)
-    octave::interpreter::add_atexit_function (arg);
+    interp.add_atexit_fcn (arg);
   else
     {
-      bool found = interp.remove_atexit_function (arg);
+      bool found = interp.remove_atexit_fcn (arg);
 
       if (nargout > 0)
         retval = ovl (found);
@@ -433,6 +433,7 @@
   interpreter::interpreter (application *app_context)
     : m_app_context (app_context),
       m_tmp_files (),
+      m_atexit_fcns (),
       m_display_info (),
       m_environment (),
       m_settings (),
@@ -1216,16 +1217,10 @@
 
     OCTAVE_SAFE_CALL (m_input_system.clear_input_event_hooks, ());
 
-    while (! atexit_functions.empty ())
-      {
-        std::string fcn = atexit_functions.front ();
+    // Any atexit functions added after this function call won't be
+    // executed.
 
-        atexit_functions.pop_front ();
-
-        OCTAVE_SAFE_CALL (feval, (fcn, octave_value_list (), 0));
-
-        OCTAVE_SAFE_CALL (flush_stdout, ());
-      }
+    execute_atexit_fcns ();
 
     // Do this explicitly so that destructors for mex file objects
     // are called, so that functions registered with mexAtExit are
@@ -1265,6 +1260,20 @@
     // OCTAVE_SAFE_CALL (singleton_cleanup_list::cleanup, ());
   }
 
+  void interpreter::execute_atexit_fcns (void)
+  {
+    while (! m_atexit_fcns.empty ())
+      {
+        std::string fcn = m_atexit_fcns.front ();
+
+        m_atexit_fcns.pop_front ();
+
+        OCTAVE_SAFE_CALL (feval, (fcn, octave_value_list (), 0));
+
+        OCTAVE_SAFE_CALL (flush_stdout, ());
+      }
+  }
+
   tree_evaluator& interpreter::get_evaluator (void)
   {
     return m_evaluator;
@@ -1786,25 +1795,21 @@
     throw exit_exception (exit_status);
   }
 
-  // Functions to call when the interpreter exits.
-
-  std::list<std::string> interpreter::atexit_functions;
-
-  void interpreter::add_atexit_function (const std::string& fname)
+  void interpreter::add_atexit_fcn (const std::string& fname)
   {
-    atexit_functions.push_front (fname);
+    m_atexit_fcns.push_front (fname);
   }
 
-  bool interpreter::remove_atexit_function (const std::string& fname)
+  bool interpreter::remove_atexit_fcn (const std::string& fname)
   {
     bool found = false;
 
-    for (auto it = atexit_functions.begin ();
-         it != atexit_functions.end (); it++)
+    for (auto it = m_atexit_fcns.begin ();
+         it != m_atexit_fcns.end (); it++)
       {
         if (*it == fname)
           {
-            atexit_functions.erase (it);
+            m_atexit_fcns.erase (it);
             found = true;
             break;
           }
@@ -1813,6 +1818,22 @@
     return found;
   }
 
+  void interpreter::add_atexit_function (const std::string& fname)
+  {
+    interpreter& interp
+      = __get_interpreter__ ("interpreter::add_atexit_function");
+
+    interp.add_atexit_fcn (fname);
+  }
+
+  bool interpreter::remove_atexit_function (const std::string& fname)
+  {
+    interpreter& interp
+      = __get_interpreter__ ("interpreter::remove_atexit_function");
+
+    return interp.remove_atexit_fcn (fname);
+  }
+
   // What internal options get configured by --traditional.
 
   void interpreter::maximum_braindamage (void)
--- a/libinterp/corefcn/interpreter.h	Thu Nov 14 11:14:25 2019 -0800
+++ b/libinterp/corefcn/interpreter.h	Thu Nov 14 15:18:15 2019 -0500
@@ -448,8 +448,14 @@
       return m_executing_finish_script;
     }
 
+    void add_atexit_fcn (const std::string& fname);
+
+    bool remove_atexit_fcn (const std::string& fname);
+
+    OCTAVE_DEPRECATED (6, "use interpreter::add_atexit_fcn member function instead")
     static void add_atexit_function (const std::string& fname);
 
+    OCTAVE_DEPRECATED (6, "use interpreter::remove_atexit_fcn member function instead")
     static bool remove_atexit_function (const std::string& fname);
 
     static interpreter * the_interpreter (void) { return instance; }
@@ -466,8 +472,6 @@
 
     OCTAVE_THREAD_LOCAL static interpreter *instance;
 
-    static std::list<std::string> atexit_functions;
-
     void display_startup_message (void) const;
 
     int execute_startup_files (void);
@@ -480,10 +484,14 @@
 
     void cleanup (void);
 
+    void execute_atexit_fcns (void);
+
     application *m_app_context;
 
     temporary_file_list m_tmp_files;
 
+    std::list<std::string> m_atexit_fcns;
+
     display_info m_display_info;
 
     environment m_environment;