21 inline int* s_debug_value() {
22 static int s_debug_value = ::getenv(
"DD4HEP_TRACE") == 0 ? 0 : 1;
23 return &s_debug_value;
28 return *s_debug_value() ? true :
false;
32 int *ptr = s_debug_value();
33 bool old_value = *ptr;
34 *ptr = new_value ? 1 : 0;
38 #if defined(__linux) && !defined(__APPLE__)
39 #define DD4HEP_PARSERS_NO_ROOT
43 #if !defined(DD4HEP_PARSERS_NO_ROOT)
51 #define MAKE_GAUDI_PLUGIN_SERVICE_ENTRY(n,v) "dd4hep_pluginmgr_" #n "_V" #v
52 #define MAKE_FUNC(name,version) MAKE_GAUDI_PLUGIN_SERVICE_ENTRY(name,version)
55 struct PluginInterface {
57 int (*setDebug)(
int new_value);
59 void (*add)(
const char* identifier,
61 const char* signature,
62 const char* return_type);
63 PluginInterface() noexcept(
false);
64 static PluginInterface& instance() noexcept(
false) {
65 static PluginInterface s_instance;
70 template <
typename FUNCTION>
struct _FP {
71 union {
void* ptr; FUNCTION fcn; } fptr;
72 _FP(FUNCTION func) { fptr.fcn = func; }
73 _FP(
void*
_p) { fptr.ptr =
_p; }
77 static inline T get_func(
void*
handle,
const char* plugin,
const char* entry) {
78 #if !defined(DD4HEP_PARSERS_NO_ROOT)
79 _FP<Func_t> fun(gSystem->DynFindSymbol(plugin,entry));
80 _FP<T> fp(fun.fptr.ptr);
83 _FP<T> fp(::dlsym(
handle, entry));
84 if ( !fp.fptr.ptr ) fp.fptr.ptr = ::dlsym(0, entry);
86 if ( 0 == fp.fptr.ptr ) {
87 std::string err =
"dd4hep:PluginService: Failed to access symbol "
88 "\""+std::string(entry)+
"\" in plugin library "+std::string(plugin)+
89 " ["+std::string(::strerror(errno))+
"]";
90 throw std::runtime_error(err);
95 PluginInterface::PluginInterface() noexcept(
false)
96 : getDebug(0), setDebug(0), create(
nullptr), add(
nullptr)
99 const char* plugin_name = ::getenv(
"DD4HEP_PLUGINMGR");
100 #if defined(__linux) && !defined(__APPLE__)
101 if ( 0 == plugin_name ) plugin_name =
"libDD4hepGaudiPluginMgr.so";
103 if ( 0 == plugin_name ) plugin_name =
"libDD4hepGaudiPluginMgr";
105 #if defined(DD4HEP_PARSERS_NO_ROOT)
106 struct handle_guard {
107 void* _handle {
nullptr};
108 handle_guard(
void* hdl) : _handle(hdl) {
111 if ( _handle ) ::dlclose(_handle);
115 static handle_guard _guard(
nullptr);
116 if (
nullptr == _guard._handle ) {
117 _guard._handle =
handle = ::dlopen(plugin_name, RTLD_LAZY | RTLD_GLOBAL);
120 throw std::runtime_error(
"Failed to load plugin manager library: "+std::string(plugin_name));
123 if ( 0 != gSystem->Load(plugin_name) ) {}
129 add = get_func< void (*) (
const char* identifier,
131 const char* signature,
138 m_debug = PluginInterface::instance().setDebug(dbg);
143 PluginInterface::instance().setDebug(
m_debug);
148 std::string factoryname =
"Create("+name+
")";
149 std::string msg =
"\t\tNo factory with name " + factoryname +
" for type " + name +
" found.\n"
150 "\t\tPlease check library load path and/or plugin factory name.";
155 return PluginInterface::instance().create(
id.c_str(),
info.name());
160 const std::type_info& signature_type,
161 const std::type_info& return_type)
164 printout(INFO,
"PluginService",
"+++ Declared factory[%s] with signature %s type:%s.",
165 id.c_str(),signature_type.name(),return_type.name());
167 PluginInterface::instance().add(
id.c_str(),std::move(stub),signature_type.name(),return_type.name());
172 const std::type_info& signature,
174 bool dbg = PluginInterface::instance().getDebug();
176 std::stringstream str;
177 str <<
"Factory requested: " <<
id <<
" (" <<
typeid(signature).name() <<
") :" << msg;
178 printout(ERROR,
"PluginService",
"%s", str.str().c_str());
181 str <<
"Stub is invalid!";
182 printout(ERROR,
"PluginService",
"%s", str.str().c_str());