Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:17:01

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 // Framework include files
0015 #include <DD4hep/Plugins.h>
0016 #include <cstdlib>
0017 
0018 using namespace dd4hep;
0019 
0020 namespace {
0021   inline int* s_debug_value()   {
0022     static int s_debug_value = ::getenv("DD4HEP_TRACE") == 0 ? 0 : 1;
0023     return &s_debug_value;
0024   }
0025 }
0026 
0027 bool PluginService::debug()  {
0028   return *s_debug_value() ? true : false;
0029 }
0030 
0031 bool PluginService::setDebug(bool new_value)   {
0032   int *ptr = s_debug_value();
0033   bool old_value = *ptr;
0034   *ptr = new_value ? 1 : 0;
0035   return old_value;
0036 }
0037 
0038 #if defined(__linux) && !defined(__APPLE__)
0039 #define DD4HEP_PARSERS_NO_ROOT
0040 #endif
0041 
0042 #include <DD4hep/Printout.h>
0043 #if !defined(DD4HEP_PARSERS_NO_ROOT)
0044 #include <TSystem.h>
0045 #else
0046 #include <dlfcn.h>
0047 #endif
0048 #include <cstring>
0049 
0050 
0051 #define MAKE_GAUDI_PLUGIN_SERVICE_ENTRY(n,v)     "dd4hep_pluginmgr_" #n "_V" #v
0052 #define MAKE_FUNC(name,version)  MAKE_GAUDI_PLUGIN_SERVICE_ENTRY(name,version)
0053 
0054 namespace   {
0055   struct PluginInterface  {
0056     int (*getDebug)();
0057     int (*setDebug)(int new_value);
0058     PluginService::stub_t (*create)(const char* identifier, const char* signature);
0059     void  (*add)(const char* identifier, 
0060                  PluginService::stub_t&& creator_stub, 
0061                  const char* signature, 
0062                  const char* return_type);
0063     PluginInterface() noexcept(false);
0064     static PluginInterface& instance()  noexcept(false)   {
0065       static PluginInterface s_instance;
0066       return s_instance;
0067     }
0068   };
0069 
0070   template <typename FUNCTION> struct _FP {
0071     union { void* ptr; FUNCTION fcn; } fptr;
0072     _FP(FUNCTION func)         {  fptr.fcn = func;        }
0073     _FP(void* _p)              {  fptr.ptr = _p;          }
0074   };
0075 
0076   template <typename T> 
0077   static inline T get_func(void* handle, const char* plugin, const char* entry)  {
0078 #if !defined(DD4HEP_PARSERS_NO_ROOT)
0079     _FP<Func_t> fun(gSystem->DynFindSymbol(plugin,entry));
0080     _FP<T> fp(fun.fptr.ptr);
0081     if ( handle ) {}
0082 #else
0083     _FP<T> fp(::dlsym(handle, entry));
0084     if ( !fp.fptr.ptr ) fp.fptr.ptr = ::dlsym(0, entry);
0085 #endif
0086     if ( 0 == fp.fptr.ptr )      {
0087       std::string err = "dd4hep:PluginService: Failed to access symbol "
0088         "\""+std::string(entry)+"\" in plugin library "+std::string(plugin)+
0089         " ["+std::string(::strerror(errno))+"]";
0090       throw std::runtime_error(err);
0091     }
0092     return fp.fptr.fcn;
0093   }
0094 
0095   PluginInterface::PluginInterface()  noexcept(false)
0096     : getDebug(0), setDebug(0), create(nullptr), add(nullptr)
0097   {
0098     void* handle = 0;
0099     const char* plugin_name = ::getenv("DD4HEP_PLUGINMGR");
0100 #if defined(__linux) && !defined(__APPLE__)
0101     if ( 0 == plugin_name ) plugin_name = "libDD4hepGaudiPluginMgr.so";
0102 #else
0103     if ( 0 == plugin_name ) plugin_name = "libDD4hepGaudiPluginMgr";
0104 #endif
0105 #if defined(DD4HEP_PARSERS_NO_ROOT)
0106     struct handle_guard  {
0107       void* _handle {nullptr};
0108       handle_guard(void* hdl) : _handle(hdl) {
0109       }
0110       ~handle_guard()  {
0111     if ( _handle ) ::dlclose(_handle);
0112     _handle = nullptr;
0113       }
0114     };
0115     static handle_guard _guard(nullptr);
0116     if ( nullptr == _guard._handle )   {
0117       _guard._handle = handle = ::dlopen(plugin_name, RTLD_LAZY | RTLD_GLOBAL);
0118     }
0119     if ( !handle )   {
0120       throw std::runtime_error("Failed to load plugin manager library: "+std::string(plugin_name));
0121     }
0122 #else
0123     if ( 0 != gSystem->Load(plugin_name) ) {}
0124 #endif
0125     getDebug = get_func< int (*) ()>(handle, plugin_name,MAKE_FUNC(getdebug,DD4HEP_PLUGINSVC_VERSION));
0126     setDebug = get_func< int (*) (int)>(handle, plugin_name,MAKE_FUNC(setdebug,DD4HEP_PLUGINSVC_VERSION));
0127     create   = get_func< PluginService::stub_t (*)(const char*,
0128                                                    const char*)>(handle, plugin_name,MAKE_FUNC(create,DD4HEP_PLUGINSVC_VERSION));
0129     add      = get_func< void (*) (const char* identifier, 
0130                                    PluginService::stub_t&& creator_stub, 
0131                                    const char* signature, 
0132                                    const char* return_type)>(handle, plugin_name,MAKE_FUNC(add_factory,DD4HEP_PLUGINSVC_VERSION));
0133   }
0134 }
0135 
0136 /// Default constructor
0137 PluginDebug::PluginDebug(int dbg)  noexcept(false) : m_debug(0) {
0138   m_debug = PluginInterface::instance().setDebug(dbg);
0139 }
0140 
0141 /// Default destructor
0142 PluginDebug::~PluginDebug()   noexcept(false)   {
0143   PluginInterface::instance().setDebug(m_debug);
0144 }
0145 
0146 /// Helper to check factory existence
0147 std::string PluginDebug::missingFactory(const std::string& name) const {
0148   std::string factoryname = "Create("+name+")";
0149   std::string msg = "\t\tNo factory with name " + factoryname + " for type " + name + " found.\n"
0150     "\t\tPlease check library load path and/or plugin factory name.";
0151   return msg;
0152 }
0153 
0154 PluginService::stub_t PluginService::getCreator(const std::string& id, const std::type_info& info)  {
0155   return PluginInterface::instance().create(id.c_str(), info.name());
0156 }
0157 
0158 void PluginService::addFactory(const std::string& id,
0159                                PluginService::stub_t&& stub,
0160                                const std::type_info&  signature_type,
0161                                const std::type_info&  return_type)
0162 {
0163   if ( PluginService::debug() )  {
0164     printout(INFO,"PluginService","+++ Declared factory[%s] with signature %s type:%s.",
0165              id.c_str(),signature_type.name(),return_type.name());
0166   }
0167   PluginInterface::instance().add(id.c_str(),std::move(stub),signature_type.name(),return_type.name());
0168 }
0169 
0170 void PluginService::print_bad_cast(const std::string& id,
0171                                    const stub_t& stub,
0172                                    const std::type_info& signature,
0173                                    const char* msg)   {
0174   bool dbg = PluginInterface::instance().getDebug();
0175   if ( dbg )   {
0176     std::stringstream str;
0177     str << "Factory requested: " << id << " (" << typeid(signature).name() << ") :" << msg;
0178     printout(ERROR,"PluginService","%s", str.str().c_str());
0179     str.str("");
0180     if ( !any_has_value(stub) )  {
0181       str << "Stub is invalid!";
0182       printout(ERROR,"PluginService","%s", str.str().c_str());
0183     }
0184   }
0185 }