diff --git a/src/core/PlumedMain.cpp b/src/core/PlumedMain.cpp
index 1762a92e07..db604fdd3f 100644
--- a/src/core/PlumedMain.cpp
+++ b/src/core/PlumedMain.cpp
@@ -1091,7 +1091,7 @@ void PlumedMain::update() {
}
}
-void PlumedMain::load(const std::string& fileName, const bool loadGlobal) {
+void PlumedMain::load(const std::string& fileName) {
if(DLLoader::installed()) {
std::string libName=fileName;
size_t n=libName.find_last_of(".");
@@ -1118,7 +1118,7 @@ void PlumedMain::load(const std::string& fileName, const bool loadGlobal) {
base="./"+base;
}
libName=base+"."+config::getSoExt();
- void *p=dlloader.load(libName,loadGlobal);
+ void *p=dlloader.load(libName);
if(!p) {
plumed_error()<<"I cannot load library " << fileName << " " << dlloader.error();
}
diff --git a/src/core/PlumedMain.h b/src/core/PlumedMain.h
index 73809aa243..635dc96379 100644
--- a/src/core/PlumedMain.h
+++ b/src/core/PlumedMain.h
@@ -368,7 +368,7 @@ class PlumedMain:
/// Stop the run
void exit(int c=0);
/// Load a shared library
- void load(const std::string&, bool=false);
+ void load(const std::string&);
/// Get the suffix string
const std::string & getSuffix()const;
/// Set the suffix string
diff --git a/src/setup/Load.cpp b/src/setup/Load.cpp
index 36b10902ae..03283662e5 100644
--- a/src/setup/Load.cpp
+++ b/src/setup/Load.cpp
@@ -106,7 +106,6 @@ PLUMED_REGISTER_ACTION(Load,"LOAD")
void Load::registerKeywords( Keywords& keys ) {
ActionSetup::registerKeywords(keys);
keys.add("compulsory","FILE","file to be loaded");
- keys.addFlag("GLOBAL",false,"when selected the shared object is LOADed with RTLD_GLOBAL instead of RTLD_LOCAL");
}
Load::Load(const ActionOptions&ao):
@@ -115,10 +114,8 @@ Load::Load(const ActionOptions&ao):
{
std::string f;
parse("FILE",f);
- bool loadWithGlobal=false;
- parseFlag("GLOBAL",loadWithGlobal);
checkRead();
- plumed.load(f,loadWithGlobal);
+ plumed.load(f);
}
}
diff --git a/src/tools/DLLoader.cpp b/src/tools/DLLoader.cpp
index ec6527d825..e7139383fb 100644
--- a/src/tools/DLLoader.cpp
+++ b/src/tools/DLLoader.cpp
@@ -20,6 +20,7 @@
along with plumed. If not, see .
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
#include "DLLoader.h"
+
#include
#ifdef __PLUMED_HAS_DLOPEN
@@ -37,13 +38,9 @@ bool DLLoader::installed() {
}
-void* DLLoader::load(const std::string&s, const bool useGlobal) {
+void* DLLoader::load(const std::string&s) {
#ifdef __PLUMED_HAS_DLOPEN
- void* p=nullptr;
- if (useGlobal)
- p=dlopen(s.c_str(),RTLD_NOW|RTLD_GLOBAL);
- else
- p=dlopen(s.c_str(),RTLD_NOW|RTLD_LOCAL);
+ void* p=dlopen(s.c_str(),RTLD_NOW|RTLD_LOCAL);
if(!p) {
lastError=dlerror();
} else {
@@ -79,5 +76,41 @@ DLLoader::DLLoader() {
// do nothing
}
+DLLoader::EnsureGlobalDLOpen::EnsureGlobalDLOpen(const void *symbol) noexcept {
+#ifdef __PLUMED_HAS_DLOPEN
+#ifdef __PLUMED_HAS_DLADDR
+ Dl_info info;
+ // from the manual:
+ // If the address specified in addr could not be matched to a shared
+ // object, then these functions return 0. In this case, an error
+ // message is not available via dlerror(3).
+ int zeroIsError=dladdr(symbol, &info);
+ if(zeroIsError!=0) {
+ //This "promotes" to GLOBAL the object with the symbol pointed by ptr
+ handle_ = dlopen(info.dli_fname, RTLD_GLOBAL | RTLD_NOW);
+ } else {
+ std::fprintf(stderr,
+ "+++WARNING+++"
+ "Failure in finding any object that contains the symbol %p.\n",
+ symbol);
+
+ }
+#else
+ std::fprintf(stderr,
+ "+++WARNING+++"
+ "I can't use dladdr for promoting the library containing the symbol %p.\n"
+ "This system seems not to support dladdr",
+ symbol);
+#endif //__PLUMED_HAS_DLADDR
+#endif //__PLUMED_HAS_DLOPEN
+}
+DLLoader::EnsureGlobalDLOpen::~EnsureGlobalDLOpen() {
+#ifdef __PLUMED_HAS_DLOPEN
+ if (handle_) {
+ dlclose(handle_);
+ }
+#endif //__PLUMED_HAS_DLOPEN
}
+
+} // namespace PLMD
diff --git a/src/tools/DLLoader.h b/src/tools/DLLoader.h
index 312f1f3178..e73d244ec0 100644
--- a/src/tools/DLLoader.h
+++ b/src/tools/DLLoader.h
@@ -50,11 +50,24 @@ class DLLoader {
/// Cleanup
~DLLoader();
/// Load a library, returning its handle
- void* load(const std::string&, bool=false);
+ void* load(const std::string&);
/// Returns the last error in dynamic loader
const std::string & error();
/// Returns true if the dynamic loader is available (on some systems it may not).
static bool installed();
+
+ /// RAII helper for promoting RTLD_LOCAL loaded objects to RTLD_GLOBAL
+ class EnsureGlobalDLOpen {
+ void* handle_=nullptr;
+ public:
+ /// makes sure that object defining ptr is globally available
+ explicit EnsureGlobalDLOpen(const void* symbol) noexcept;
+ /// dlclose the dlopened object
+ ~EnsureGlobalDLOpen();
+ ///Confevert a const reference to a
+ template EnsureGlobalDLOpen(const T&p) noexcept
+ : EnsureGlobalDLOpen(reinterpret_cast(p)) {}
+ };
};
} // namespace PLMD