MarlinMT  0.1.0
PluginManager.cc
Go to the documentation of this file.
2 
3 // -- std headers
4 #include <dlfcn.h>
5 #include <iostream>
6 #include <cstdlib>
7 #include <algorithm>
8 #include <set>
9 
10 // -- marlinmt headers
11 #include <marlinmt/Utils.h>
12 
13 namespace marlinmt {
14 
16  _logger = Logging::createLogger( "PluginManager" ) ;
17  _logger->setLevel<MESSAGE>() ;
18  }
19 
20  //--------------------------------------------------------------------------
21 
22  void PluginManager::registerPlugin( const std::string &name, FactoryFunction factoryFunction, bool ignoreDuplicate ) {
23  lock_type lock( _mutex ) ;
24  auto factoryIter = _pluginFactories.find( name ) ;
25  if ( _pluginFactories.end() != factoryIter ) {
26  if ( not ignoreDuplicate ) {
27  MARLINMT_THROW( "Plugin '" + name + "' already registered" ) ;
28  }
29  _logger->log<DEBUG2>() << "Plugin '" << name << "' already registered. Skipping ..." << std::endl ;
30  }
31  else {
32  FactoryData fdata {} ;
34  fdata._factory = factoryFunction ;
35  _pluginFactories.insert( PluginFactoryMap::value_type( name, fdata ) ) ;
36  _logger->log<DEBUG5>() << "New plugin registered: '" << name << "'" <<std::endl ;
37  }
38  }
39 
40  //--------------------------------------------------------------------------
41 
42  std::vector<std::string> PluginManager::pluginNames() const {
43  lock_type lock( _mutex ) ;
44  return details::keys( _pluginFactories ) ;
45  }
46 
47  //--------------------------------------------------------------------------
48 
49  bool PluginManager::pluginRegistered( const std::string &name ) const {
50  lock_type lock( _mutex ) ;
51  return ( _pluginFactories.find( name ) != _pluginFactories.end() ) ;
52  }
53 
54  //--------------------------------------------------------------------------
55 
57  static PluginManager mgr;
58  return mgr;
59  }
60 
61  //--------------------------------------------------------------------------
62 
63  void PluginManager::loadLibrary( const std::string &library ) {
64  lock_type lock( _mutex ) ;
65  doLoadLibrary( library ) ;
66  }
67 
68  //--------------------------------------------------------------------------
69 
70  void PluginManager::loadLibraries( const std::vector<std::string> &libraries ) {
71  lock_type lock( _mutex ) ;
72  for ( const auto &library : libraries ) {
73  doLoadLibrary( library ) ;
74  }
75  }
76 
77  //--------------------------------------------------------------------------
78 
79  void PluginManager::dump() const {
80  lock_type lock( _mutex ) ;
81  std::map<std::string, std::vector<std::string>> pluginMap ;
82  _logger->log<MESSAGE>() << "------------------------------------" << std::endl ;
83  _logger->log<MESSAGE>() << " ** MarlinMT plugin manager dump ** " << std::endl ;
84  if( _pluginFactories.empty() ) {
85  _logger->log<MESSAGE>() << " No plugin entry !" << std::endl ;
86  }
87  else {
88  for ( auto iter : _pluginFactories ) {
89  pluginMap[iter.second._libraryName].push_back( iter.first ) ;
90  }
91  for ( auto iter : pluginMap ) {
92  _logger->log<MESSAGE>() << "Library: " << iter.first << std::endl ;
93  for( auto p : iter.second ) {
94  _logger->log<MESSAGE>() << " - " << p << std::endl ;
95  }
96  }
97  }
98  _logger->log<MESSAGE>() << "----------------------------------" << std::endl ;
99  }
100 
101  //--------------------------------------------------------------------------
102 
104  return _logger ;
105  }
106 
107  //--------------------------------------------------------------------------
108 
109  void PluginManager::doLoadLibrary( const std::string &library ) {
110  auto libraryPath = std::filesystem::absolute(library) ;
111  auto libIter = _libraries.find( libraryPath ) ;
112  auto libraryName = libraryPath.filename() ;
113  auto libraryStr = libraryPath.string() ;
114  _logger->log<MESSAGE>() << "Loading shared library : " << libraryStr << std::endl ;
115  if( _libraries.end() != libIter ) {
116  MARLINMT_THROW( "ERROR loading shared library '" + libraryStr + "': duplicated library" ) ;
117  }
118  _currentLibrary = libraryStr ;
119  void* libPointer = ::dlopen( _currentLibrary.c_str() , RTLD_LAZY | RTLD_GLOBAL) ;
120  _currentLibrary.clear() ;
121  if( nullptr == libPointer ) {
122  MARLINMT_THROW( "ERROR loading shared library '" + libraryStr + "': " + std::string(dlerror()) ) ;
123  }
124  _libraries.insert( {libraryStr, libPointer} ) ;
125  }
126 
127 } // namespace marlinmt
Logger _logger
The plugin manager logger.
std::string _libraryName
The name of the library of the plugin.
Definition: PluginManager.h:75
static Logger createLogger(const std::string &name)
Create a standalone logger instance.
Definition: Logging.cc:5
void doLoadLibrary(const std::string &library)
the workhorse !
void loadLibrary(const std::string &library)
Load a shared library to populate the list of plugins.
Logging::Logger Logger
Definition: PluginManager.h:82
std::string _currentLibrary
The current library being loaded.
bool pluginRegistered(const std::string &name) const
Whether the plugin with of a given name is registered.
#define MARLINMT_THROW(message)
Definition: Exceptions.h:8
void loadLibraries(const std::vector< std::string > &libraries)
Load shared libraries to populate the list of plugins.
std::vector< std::string > pluginNames() const
Get all registered plugin name.
mutex_type _mutex
The synchronization mutex.
void dump() const
Dump plugin manager content in console.
Logger logger() const
Get the plugin manager logger.
PluginManager()
Constructor.
void registerPlugin(const std::string &name, bool ignoreDuplicate=false)
Register a new plugin to the manager.
PluginManager singleton class Responsible for loading shared libraries and collecting processor facto...
Definition: PluginManager.h:64
std::lock_guard< mutex_type > lock_type
Definition: PluginManager.h:84
LibraryList _libraries
The list of loaded libraries.
static PluginManager & instance()
Get the plugin manager instance.
PluginFactoryMap _pluginFactories
The map of plugin factories.
std::vector< K > keys(const std::map< K, V > &m)
Definition: Utils.h:539