changeset 23627:0a6e87804cab

don't use singleton pattern for dynamic_loader class * dynamic-ld.h, dynamic-ld.cc (dynamic_loader): Don't use singleton. Use Octave coding standard for member names. Change all uses. * interpreter.h, interpreter.cc (interpreter::m_dynamic_loader): New data member. (interpreter::get_dynamic_loader): New access function. * interpreter-private.h interpreter-private.cc (__get_dynamic_loader__): New function.
author John W. Eaton <jwe@octave.org>
date Fri, 16 Jun 2017 14:42:35 -0400
parents fea9218bd43d
children fca2f775ab4c
files libinterp/corefcn/dynamic-ld.cc libinterp/corefcn/dynamic-ld.h libinterp/corefcn/interpreter-private.cc libinterp/corefcn/interpreter-private.h libinterp/corefcn/interpreter.cc libinterp/corefcn/interpreter.h libinterp/octave-value/ov-dld-fcn.cc libinterp/octave-value/ov-mex-fcn.cc libinterp/parse-tree/oct-parse.in.yy
diffstat 9 files changed, 122 insertions(+), 152 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/dynamic-ld.cc	Fri Jun 16 16:25:56 2017 -0400
+++ b/libinterp/corefcn/dynamic-ld.cc	Fri Jun 16 14:42:35 2017 -0400
@@ -36,6 +36,7 @@
 #include "defun.h"
 #include "dynamic-ld.h"
 #include "interpreter-private.h"
+#include "interpreter.h"
 #include "ov-fcn.h"
 #include "ov-dld-fcn.h"
 #include "ov-mex-fcn.h"
@@ -52,7 +53,7 @@
   void
   dynamic_loader::shlibs_list::append (const dynamic_library& shl)
   {
-    lib_list.push_back (shl);
+    m_lib_list.push_back (shl);
   }
 
   std::list<std::string>
@@ -60,11 +61,11 @@
   {
     std::list<std::string> removed_fcns;
 
-    for (iterator p = lib_list.begin (); p != lib_list.end (); p++)
+    for (iterator p = m_lib_list.begin (); p != m_lib_list.end (); p++)
       {
         if (*p == shl)
           {
-            lib_list.erase (p);
+            m_lib_list.erase (p);
 
             removed_fcns = shl.close ();
 
@@ -80,7 +81,7 @@
   {
     dynamic_library retval;
 
-    for (const auto& lib : lib_list)
+    for (const auto& lib : m_lib_list)
       {
         if (lib.file_name () == file_name)
           {
@@ -96,46 +97,26 @@
   dynamic_loader::shlibs_list::display (void) const
   {
     std::cerr << "current shared libraries:" << std::endl;
-    for (const auto& lib : lib_list)
+    for (const auto& lib : m_lib_list)
       std::cerr << "  " << lib.file_name () << std::endl;
   }
 
-  dynamic_loader *dynamic_loader::instance = nullptr;
-
-  bool dynamic_loader::doing_load = false;
-
-  bool
-  dynamic_loader::instance_ok (void)
-  {
-    bool retval = true;
-
-    if (! instance)
-      {
-        instance = new dynamic_loader ();
-
-        if (instance)
-          singleton_cleanup_list::add (cleanup_instance);
-      }
-
-    if (! instance)
-      error ("unable to create dynamic loader object!");
-
-    return retval;
-  }
-
   void
-  dynamic_loader::do_clear_function (const std::string& fcn_name)
+  dynamic_loader::clear_function (const std::string& fcn_name)
   {
     warning_with_id ("Octave:reload-forces-clear", "  %s", fcn_name.c_str ());
 
-    symbol_table& symtab
-      = __get_symbol_table__ ("dynamic_loader::do_clear_function");
+    // FIXME: is there a way to avoid this?  Can we manage the list of
+    // functions that are loaded in the symbol table completely outside
+    // of the dynamic_loader class?
+
+    symbol_table& symtab = m_interpreter.get_symbol_table ();
 
     symtab.clear_dld_function (fcn_name);
   }
 
   void
-  dynamic_loader::do_clear (dynamic_library& oct_file)
+  dynamic_loader::clear (dynamic_library& oct_file)
   {
     if (oct_file.number_of_functions_loaded () > 1)
       {
@@ -143,17 +124,20 @@
                          "reloading %s clears the following functions:",
                          oct_file.file_name ().c_str ());
 
-        std::list<std::string> removed_fcns = loaded_shlibs.remove (oct_file);
+        std::list<std::string> removed_fcns = m_loaded_shlibs.remove (oct_file);
 
         for (const auto& fcn_name : removed_fcns)
-          do_clear_function (fcn_name);
+          clear_function (fcn_name);
       }
     else
       {
-        std::list<std::string> removed_fcns = loaded_shlibs.remove (oct_file);
+        std::list<std::string> removed_fcns = m_loaded_shlibs.remove (oct_file);
 
-        symbol_table& symtab
-          = __get_symbol_table__ ("dynamic_loader::do_clear");
+        // FIXME: is there a way to avoid this?  Can we manage the list
+        // of functions that are loaded in the symbol table completely
+        // outside of the dynamic_loader class?
+
+        symbol_table& symtab = m_interpreter.get_symbol_table ();
 
         for (const auto& fcn_name : removed_fcns)
           symtab.clear_dld_function (fcn_name);
@@ -161,29 +145,29 @@
   }
 
   octave_function *
-  dynamic_loader::do_load_oct (const std::string& fcn_name,
-                               const std::string& file_name,
-                               bool relative)
+  dynamic_loader::load_oct (const std::string& fcn_name,
+                            const std::string& file_name,
+                            bool relative)
   {
     octave_function *retval = nullptr;
 
     unwind_protect frame;
 
-    frame.protect_var (dynamic_loader::doing_load);
+    frame.protect_var (m_doing_load);
 
-    doing_load = true;
+    m_doing_load = true;
 
-    dynamic_library oct_file = loaded_shlibs.find_file (file_name);
+    dynamic_library oct_file = m_loaded_shlibs.find_file (file_name);
 
     if (oct_file && oct_file.is_out_of_date ())
-      do_clear (oct_file);
+      clear (oct_file);
 
     if (! oct_file)
       {
         oct_file.open (file_name);
 
         if (oct_file)
-          loaded_shlibs.append (oct_file);
+          m_loaded_shlibs.append (oct_file);
       }
 
     if (! oct_file)
@@ -215,29 +199,29 @@
   }
 
   octave_function *
-  dynamic_loader::do_load_mex (const std::string& fcn_name,
-                               const std::string& file_name,
-                               bool /*relative*/)
+  dynamic_loader::load_mex (const std::string& fcn_name,
+                            const std::string& file_name,
+                            bool /*relative*/)
   {
     octave_function *retval = nullptr;
 
     unwind_protect frame;
 
-    frame.protect_var (dynamic_loader::doing_load);
+    frame.protect_var (m_doing_load);
 
-    doing_load = true;
+    m_doing_load = true;
 
-    dynamic_library mex_file = loaded_shlibs.find_file (file_name);
+    dynamic_library mex_file = m_loaded_shlibs.find_file (file_name);
 
     if (mex_file && mex_file.is_out_of_date ())
-      do_clear (mex_file);
+      clear (mex_file);
 
     if (! mex_file)
       {
         mex_file.open (file_name);
 
         if (mex_file)
-          loaded_shlibs.append (mex_file);
+          m_loaded_shlibs.append (mex_file);
       }
 
     if (! mex_file)
@@ -274,75 +258,43 @@
   }
 
   bool
-  dynamic_loader::do_remove_oct (const std::string& fcn_name,
-                                 dynamic_library& shl)
-  {
-    bool retval = false;
-
-    // We don't need to do anything if this is called because we are in
-    // the process of reloading a .oct file that has changed.
-
-    if (! doing_load)
-      {
-        retval = shl.remove (fcn_name);
-
-        if (shl.number_of_functions_loaded () == 0)
-          loaded_shlibs.remove (shl);
-      }
-
-    return retval;
-  }
-
-  bool
-  dynamic_loader::do_remove_mex (const std::string& fcn_name,
-                                 dynamic_library& shl)
+  dynamic_loader::remove_oct (const std::string& fcn_name,
+                              dynamic_library& shl)
   {
     bool retval = false;
 
     // We don't need to do anything if this is called because we are in
     // the process of reloading a .oct file that has changed.
 
-    if (! doing_load)
+    if (! m_doing_load)
       {
         retval = shl.remove (fcn_name);
 
         if (shl.number_of_functions_loaded () == 0)
-          loaded_shlibs.remove (shl);
+          m_loaded_shlibs.remove (shl);
       }
 
     return retval;
   }
 
-  octave_function *
-  dynamic_loader::load_oct (const std::string& fcn_name,
-                            const std::string& file_name,
-                            bool relative)
-  {
-    return (instance_ok ())
-      ? instance->do_load_oct (fcn_name, file_name, relative) : 0;
-  }
-
-  octave_function *
-  dynamic_loader::load_mex (const std::string& fcn_name,
-                            const std::string& file_name,
-                            bool relative)
-  {
-    return (instance_ok ())
-      ? instance->do_load_mex (fcn_name, file_name, relative) : 0;
-  }
-
-  bool
-  dynamic_loader::remove_oct (const std::string& fcn_name,
-                              dynamic_library& shl)
-  {
-    return (instance_ok ()) ? instance->do_remove_oct (fcn_name, shl) : false;
-  }
-
   bool
   dynamic_loader::remove_mex (const std::string& fcn_name,
                               dynamic_library& shl)
   {
-    return (instance_ok ()) ? instance->do_remove_mex (fcn_name, shl) : false;
+    bool retval = false;
+
+    // We don't need to do anything if this is called because we are in
+    // the process of reloading a .oct file that has changed.
+
+    if (! m_doing_load)
+      {
+        retval = shl.remove (fcn_name);
+
+        if (shl.number_of_functions_loaded () == 0)
+          m_loaded_shlibs.remove (shl);
+      }
+
+    return retval;
   }
 
   std::string
--- a/libinterp/corefcn/dynamic-ld.h	Fri Jun 16 16:25:56 2017 -0400
+++ b/libinterp/corefcn/dynamic-ld.h	Fri Jun 16 14:42:35 2017 -0400
@@ -34,6 +34,8 @@
 
 namespace octave
 {
+  class interpreter;
+
   class
   dynamic_loader
   {
@@ -47,7 +49,13 @@
       typedef std::list<octave::dynamic_library>::iterator iterator;
       typedef std::list<octave::dynamic_library>::const_iterator const_iterator;
 
-      shlibs_list (void) : lib_list () { }
+      shlibs_list (void) : m_lib_list () { }
+
+      // No copying!
+
+      shlibs_list (const shlibs_list&) = delete;
+
+      shlibs_list& operator = (const shlibs_list&) = delete;
 
       ~shlibs_list (void) = default;
 
@@ -61,22 +69,17 @@
 
     private:
 
-      // No copying!
-
-      shlibs_list (const shlibs_list&) = delete;
-
-      shlibs_list& operator = (const shlibs_list&) = delete;
-
       // List of libraries we have loaded.
-      std::list<octave::dynamic_library> lib_list;
+      std::list<octave::dynamic_library> m_lib_list;
     };
 
-  protected:
-
-    dynamic_loader (void) : loaded_shlibs () { }
 
   public:
 
+    dynamic_loader (interpreter& interp)
+      : m_interpreter (interp), m_loaded_shlibs (), m_doing_load (false)
+    { }
+
     // No copying!
 
     dynamic_loader (const dynamic_loader&) = delete;
@@ -85,53 +88,33 @@
 
     virtual ~dynamic_loader (void) = default;
 
-    static octave_function *
+    octave_function *
     load_oct (const std::string& fcn_name,
               const std::string& file_name = "",
               bool relative = false);
 
-    static octave_function *
+    octave_function *
     load_mex (const std::string& fcn_name,
               const std::string& file_name = "",
               bool relative = false);
 
-    static bool remove_oct (const std::string& fcn_name,
+    bool remove_oct (const std::string& fcn_name,
                             octave::dynamic_library& shl);
 
-    static bool remove_mex (const std::string& fcn_name,
+    bool remove_mex (const std::string& fcn_name,
                             octave::dynamic_library& shl);
 
   private:
 
-    static dynamic_loader *instance;
-
-    static void cleanup_instance (void) { delete instance; instance = 0; }
-
-    static bool instance_ok (void);
+    void clear_function (const std::string& fcn_name);
 
-    static void do_clear_function (const std::string& fcn_name);
-
-    void do_clear (octave::dynamic_library& oct_file);
-
-    octave_function *
-    do_load_oct (const std::string& fcn_name,
-                 const std::string& file_name = "",
-                 bool relative = false);
+    void clear (octave::dynamic_library& oct_file);
 
-    octave_function *
-    do_load_mex (const std::string& fcn_name,
-                 const std::string& file_name = "",
-                 bool relative = false);
-
-    bool do_remove_oct (const std::string& fcn_name, octave::dynamic_library& shl);
+    interpreter& m_interpreter;
 
-    bool do_remove_mex (const std::string& fcn_name, octave::dynamic_library& shl);
-
-    static bool doing_load;
+    shlibs_list m_loaded_shlibs;
 
-  protected:
-
-    shlibs_list loaded_shlibs;
+    bool m_doing_load;
 
     static std::string name_mangler (const std::string& name);
 
--- a/libinterp/corefcn/interpreter-private.cc	Fri Jun 16 16:25:56 2017 -0400
+++ b/libinterp/corefcn/interpreter-private.cc	Fri Jun 16 14:42:35 2017 -0400
@@ -48,6 +48,13 @@
     return *interp;
   }
 
+  dynamic_loader& __get_dynamic_loader__ (const std::string& who)
+  {
+    interpreter& interp = __get_interpreter__ (who);
+
+    return interp.get_dynamic_loader ();
+  }
+
   load_path& __get_load_path__ (const std::string& who)
   {
     interpreter& interp = __get_interpreter__ (who);
--- a/libinterp/corefcn/interpreter-private.h	Fri Jun 16 16:25:56 2017 -0400
+++ b/libinterp/corefcn/interpreter-private.h	Fri Jun 16 14:42:35 2017 -0400
@@ -33,11 +33,14 @@
 {
   class call_stack;
   class interpreter;
+  class dynamic_loader;
   class load_path;
   class tree_evaluator;
 
   extern interpreter& __get_interpreter__ (const std::string& who);
 
+  extern dynamic_loader& __get_dynamic_loader__ (const std::string& who);
+
   extern load_path& __get_load_path__ (const std::string& who);
 
   extern symbol_table& __get_symbol_table__ (const std::string& who);
--- a/libinterp/corefcn/interpreter.cc	Fri Jun 16 16:25:56 2017 -0400
+++ b/libinterp/corefcn/interpreter.cc	Fri Jun 16 14:42:35 2017 -0400
@@ -372,11 +372,18 @@
   // path.
 
   interpreter::interpreter (application *app_context)
-    : m_app_context (app_context), m_load_path (), m_symbol_table (),
-      m_evaluator (new tree_evaluator (*this)), m_interactive (false),
-      m_read_site_files (true), m_read_init_files (m_app_context != 0),
-      m_verbose (false), m_inhibit_startup_message (false),
-      m_load_path_initialized (false), m_history_initialized (false),
+    : m_app_context (app_context),
+      m_dynamic_loader (*this),
+      m_load_path (),
+      m_symbol_table (),
+      m_evaluator (new tree_evaluator (*this)),
+      m_interactive (false),
+      m_read_site_files (true),
+      m_read_init_files (m_app_context != 0),
+      m_verbose (false),
+      m_inhibit_startup_message (false),
+      m_load_path_initialized (false),
+      m_history_initialized (false),
       m_initialized (false)
   {
     if (instance)
--- a/libinterp/corefcn/interpreter.h	Fri Jun 16 16:25:56 2017 -0400
+++ b/libinterp/corefcn/interpreter.h	Fri Jun 16 14:42:35 2017 -0400
@@ -30,6 +30,7 @@
 #include "quit.h"
 #include "str-vec.h"
 
+#include "dynamic-ld.h"
 #include "load-path.h"
 #include "symtab.h"
 
@@ -134,6 +135,11 @@
       return m_initialized;
     }
 
+    dynamic_loader& get_dynamic_loader (void)
+    {
+      return m_dynamic_loader;
+    }
+
     load_path& get_load_path (void)
     {
       return m_load_path;
@@ -181,6 +187,8 @@
 
     application *m_app_context;
 
+    dynamic_loader m_dynamic_loader;
+
     load_path m_load_path;
 
     symbol_table m_symbol_table;
--- a/libinterp/octave-value/ov-dld-fcn.cc	Fri Jun 16 16:25:56 2017 -0400
+++ b/libinterp/octave-value/ov-dld-fcn.cc	Fri Jun 16 14:42:35 2017 -0400
@@ -29,6 +29,7 @@
 #include "defaults.h"
 #include "dynamic-ld.h"
 #include "error.h"
+#include "interpreter-private.h"
 #include "ovl.h"
 #include "ov-dld-fcn.h"
 #include "ov.h"
@@ -68,7 +69,10 @@
 
 octave_dld_function::~octave_dld_function (void)
 {
-  octave::dynamic_loader::remove_oct (my_name, sh_lib);
+  octave::dynamic_loader& dyn_loader
+    = octave::__get_dynamic_loader__ ("~octave_dld_function");
+
+  dyn_loader.remove_oct (my_name, sh_lib);
 }
 
 std::string
--- a/libinterp/octave-value/ov-mex-fcn.cc	Fri Jun 16 16:25:56 2017 -0400
+++ b/libinterp/octave-value/ov-mex-fcn.cc	Fri Jun 16 14:42:35 2017 -0400
@@ -63,7 +63,10 @@
   if (m_exit_fcn_ptr)
     (*m_exit_fcn_ptr) ();
 
-  octave::dynamic_loader::remove_mex (my_name, m_sh_lib);
+  octave::dynamic_loader& dyn_loader
+    = octave::__get_dynamic_loader__ ("~octave_mex_function");
+
+  dyn_loader.remove_mex (my_name, m_sh_lib);
 }
 
 std::string
--- a/libinterp/parse-tree/oct-parse.in.yy	Fri Jun 16 16:25:56 2017 -0400
+++ b/libinterp/parse-tree/oct-parse.in.yy	Fri Jun 16 14:42:35 2017 -0400
@@ -4535,12 +4535,15 @@
 
     int len = file.length ();
 
+      octave::dynamic_loader& dyn_loader
+        = __get_dynamic_loader__ ("~octave_mex_function");
+
     if (len > 4 && file.substr (len-4, len-1) == ".oct")
       {
         if (autoload && ! fcn_name.empty ())
           nm = fcn_name;
 
-        retval = octave::dynamic_loader::load_oct (nm, file, relative_lookup);
+        retval = dyn_loader.load_oct (nm, file, relative_lookup);
       }
     else if (len > 4 && file.substr (len-4, len-1) == ".mex")
       {
@@ -4553,7 +4556,7 @@
                                                   autoload, autoload,
                                                   relative_lookup, "");
 
-        retval = octave::dynamic_loader::load_mex (nm, file, relative_lookup);
+        retval = dyn_loader.load_mex (nm, file, relative_lookup);
 
         if (tmpfcn)
           retval->document (tmpfcn->doc_string ());