Module: sems
Branch: master
Commit: b0079d18998680527f33bafd34309e2c188fb1bc
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=b0079d18998680527f33bafd34309e2c188fb1bc

Author: Stefan Sayer <[email protected]>
Committer: Stefan Sayer <[email protected]>
Date:   Wed Oct  5 14:17:02 2011 +0200

use RTLD_LOCAL for loading modules (except dsm, ivr, py_sems)

other modules which to load with RTLD_GLOBAL can be set in sems.conf option
e.g. load_plugins_rtld_global=mymod.so,myothermod.so

---

 core/AmConfig.cpp         |   10 ++++++++++
 core/AmPlugIn.cpp         |   35 +++++++++++++++++++++++++++++++----
 core/AmPlugIn.h           |    5 ++++-
 core/etc/sems.conf.sample |    4 ++++
 4 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/core/AmConfig.cpp b/core/AmConfig.cpp
index 2c5c428..a1133b2 100644
--- a/core/AmConfig.cpp
+++ b/core/AmConfig.cpp
@@ -318,6 +318,16 @@ int AmConfig::readConfiguration()
   if (cfg.hasParameter("load_plugins"))
     LoadPlugins = cfg.getParameter("load_plugins");
 
+  if (cfg.hasParameter("load_plugins_rtld_global")) {
+    vector<string> rtld_global_plugins =
+      explode(cfg.getParameter("load_plugins_rtld_global"), ",");
+    for (vector<string>::iterator it=
+          rtld_global_plugins.begin(); it != rtld_global_plugins.end(); it++) {
+      AmPlugIn::instance()->set_load_rtld_global(*it);
+    }
+  }
+
+
   // exclude_plugins
   if (cfg.hasParameter("exclude_plugins"))
     ExcludePlugins = cfg.getParameter("exclude_plugins");
diff --git a/core/AmPlugIn.cpp b/core/AmPlugIn.cpp
index d27bce5..1698d59 100644
--- a/core/AmPlugIn.cpp
+++ b/core/AmPlugIn.cpp
@@ -201,7 +201,7 @@ int AmPlugIn::load(const string& directory, const string& 
plugins)
       string plugin_file = directory + "/" + plugin_name;
 
       DBG("loading %s ...\n",plugin_file.c_str());
-      if( (err = loadPlugIn(plugin_file)) < 0 ) {
+      if( (err = loadPlugIn(plugin_file, plugin_name)) < 0 ) {
         ERROR("while loading plug-in '%s'\n",plugin_file.c_str());
         return -1;
       }
@@ -228,7 +228,7 @@ int AmPlugIn::load(const string& directory, const string& 
plugins)
 
       plugin_file = directory + "/"  + plugin_file;
       DBG("loading %s...\n",plugin_file.c_str());
-      if( (err = loadPlugIn(plugin_file)) < 0 ) {
+      if( (err = loadPlugIn(plugin_file, plugin_file)) < 0 ) {
         ERROR("while loading plug-in '%s'\n",plugin_file.c_str());
         // be strict here: if plugin not loaded, stop!
         return err; 
@@ -314,9 +314,36 @@ int AmPlugIn::load(const string& directory, const string& 
plugins)
   return 0;
 }
 
-int AmPlugIn::loadPlugIn(const string& file)
+void AmPlugIn::set_load_rtld_global(const string& plugin_name) {
+  rtld_global_plugins.insert(plugin_name);
+}
+
+int AmPlugIn::loadPlugIn(const string& file, const string& plugin_name)
 {
-  void* h_dl = dlopen(file.c_str(),RTLD_NOW | RTLD_GLOBAL);
+  int dlopen_flags = RTLD_NOW;
+
+  char* pname = strdup(plugin_name.c_str());
+  char* bname = basename(pname);
+
+  // dsm, ivr and py_sems need RTLD_GLOBAL
+  if (!strcmp(bname, "dsm.so") || !strcmp(bname, "ivr.so") ||
+      !strcmp(bname, "py_sems.so")) {
+      dlopen_flags = RTLD_NOW | RTLD_GLOBAL;
+      DBG("using RTLD_NOW | RTLD_GLOBAL to dlopen '%s'\n", file.c_str());
+  }
+
+  // possibly others
+  for (std::set<string>::iterator it=rtld_global_plugins.begin();
+       it!=rtld_global_plugins.end();it++) {
+    if (!strcmp(bname, it->c_str())) {
+      dlopen_flags = RTLD_NOW | RTLD_GLOBAL;
+      DBG("using RTLD_NOW | RTLD_GLOBAL to dlopen '%s'\n", file.c_str());
+      break;
+    }
+  }
+  free(pname);
+
+  void* h_dl = dlopen(file.c_str(),dlopen_flags);
 
   if(!h_dl){
     ERROR("AmPlugIn::loadPlugIn: %s: %s\n",file.c_str(),dlerror());
diff --git a/core/AmPlugIn.h b/core/AmPlugIn.h
index d60b66b..b367f2c 100644
--- a/core/AmPlugIn.h
+++ b/core/AmPlugIn.h
@@ -88,6 +88,7 @@ class AmPlugIn : public AmPayloadProviderInterface
  private:
   static AmPlugIn* _instance;
 
+  std::set<string>                  rtld_global_plugins;
   vector<void*> dlls;
 
   std::map<int,amci_codec_t*>       codecs;
@@ -112,7 +113,7 @@ class AmPlugIn : public AmPayloadProviderInterface
   virtual ~AmPlugIn();
 
   /** @return -1 if failed, else 0. */
-  int loadPlugIn(const string& file);
+  int loadPlugIn(const string& file, const string& plugin_name);
 
   int loadAudioPlugIn(amci_exports_t* exports);
   int loadAppPlugIn(AmPluginFactory* cb);
@@ -127,6 +128,8 @@ class AmPlugIn : public AmPayloadProviderInterface
   int addPayload(amci_payload_t* p);
   int addFileFormat(amci_inoutfmt_t* f);
 
+  void set_load_rtld_global(const string& plugin_name);
+
   static AmPlugIn* instance();
   static void dispose();
 
diff --git a/core/etc/sems.conf.sample b/core/etc/sems.conf.sample
index 1685be8..f08c465 100644
--- a/core/etc/sems.conf.sample
+++ b/core/etc/sems.conf.sample
@@ -198,6 +198,10 @@ plugin_path=/usr/local/lib/sems/plug-in/
 # o py_sems: conflicts with ivr (in some cases)
 exclude_plugins=precoded_announce;py_sems
 
+# optional: load_plugins_rtld_global=<modules list>
+#
+# load these plugins with RTLD_GLOBAL (by default py_sems, dsm, ivr)
+
 # optional parameter: application
 # 
 # This controls which application is to be executed if there 

_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to