OpenASIP  2.0
Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
PluginTools Class Reference

#include <PluginTools.hh>

Collaboration diagram for PluginTools:
Collaboration graph

Public Member Functions

 PluginTools (bool lazyResolution=true, bool local=false)
 
virtual ~PluginTools ()
 
void addSearchPath (const std::string &searchPath)
 
void removeSearchPath (const std::string &searchPath)
 
void clearSearchPaths ()
 
void registerModule (const std::string &module)
 
void unregisterModule (const std::string &module)
 
void unregisterAllModules ()
 
template<typename T >
void importSymbol (const std::string &symbolName, T *&target, const std::string &module)
 
template<typename T >
void importSymbol (const std::string &symbolName, T *&target)
 

Private Types

typedef std::vector< std::string >::iterator VecIter
 
typedef std::map< std::string, void * >::iterator MapIter
 
typedef std::map< std::string, void * >::value_type ValType
 

Private Member Functions

void * loadSym (const std::string &symbolName, const std::string &module="")
 
std::string findModule (const std::string &module)
 
 PluginTools (const PluginTools &)
 Copying not allowed. More...
 
PluginToolsoperator= (const PluginTools &)
 Assignment not allowed. More...
 

Private Attributes

std::vector< std::string > searchPaths_
 Search paths of dynamic modules. More...
 
std::map< std::string, void * > modules_
 Map containing opened module handles. More...
 
bool lazyResolution_
 True if all undefined symbols should be resolved only when needed. More...
 
bool localResolution_
 True if the symbols defined in the loaded library should be made available for symbol resolution of subsequently loaded libraries. More...
 

Detailed Description

Class that handles accessing of dynamic modules for providing run-time plug-in functionality.

Class allows defining search paths, in which modules are searched. This enables registering modules without absolut paths to modules. Symbols (variables, functions) are loaded from modules and automatically cast to correct types by means of the template mechanism.

Definition at line 53 of file PluginTools.hh.

Member Typedef Documentation

◆ MapIter

typedef std::map<std::string, void*>::iterator PluginTools::MapIter
private

Definition at line 75 of file PluginTools.hh.

◆ ValType

typedef std::map<std::string, void*>::value_type PluginTools::ValType
private

Definition at line 76 of file PluginTools.hh.

◆ VecIter

typedef std::vector<std::string>::iterator PluginTools::VecIter
private

Definition at line 74 of file PluginTools.hh.

Constructor & Destructor Documentation

◆ PluginTools() [1/2]

PluginTools::PluginTools ( bool  lazyResolution = true,
bool  local = false 
)

Constructor.

The created instance has no search paths registered.

Parameters
lazyResolutionTrue if symbol resolution should be done lazily.
localResolutionTrue in case the symbols are loaded locally to the process only and not made visible to later plugin loads.
Note
Throwing C++ exceptions from plugin to the loader might not work with the lazy resolution! It's probably safest to set the argument to "false".

Definition at line 73 of file PluginTools.cc.

73  :
74  lazyResolution_(lazyResolution), localResolution_(local) {
75 }

◆ ~PluginTools()

PluginTools::~PluginTools ( )
virtual

Destructor.

Unregisters all modules.

Definition at line 83 of file PluginTools.cc.

83  {
85 }

References unregisterAllModules().

Here is the call graph for this function:

◆ PluginTools() [2/2]

PluginTools::PluginTools ( const PluginTools )
private

Copying not allowed.

Member Function Documentation

◆ addSearchPath()

void PluginTools::addSearchPath ( const std::string &  searchPath)

Adds a new search path in search path list.

Parameters
searchPathThe search path to be added.
Exceptions
FileNotFoundIf path doesn't exist.

Definition at line 95 of file PluginTools.cc.

95  {
96  if (!(FileSystem::fileExists(searchPath))) {
97  string method = "PluginTools::addSearchPath()";
98  string message = "Path doesn't exist";
99  throw FileNotFound(__FILE__, __LINE__, method, message);
100  }
101  searchPaths_.push_back(searchPath);
102 }

References FileSystem::fileExists(), and searchPaths_.

Referenced by ProgramImageGenerator::createCompressor(), LLVMBackend::createPlugin(), GenerateProcessor::listICDecPluginParameters(), GenerateProcessorDialog::loadICDecoderGeneratorPlugin(), ProGe::ProGeUI::loadICDecoderGeneratorPlugin(), and CompiledSimController::reset().

Here is the call graph for this function:

◆ clearSearchPaths()

void PluginTools::clearSearchPaths ( )

Clears all search paths from search path list.

Definition at line 119 of file PluginTools.cc.

119  {
120  searchPaths_.clear();
121 }

References searchPaths_.

◆ findModule()

string PluginTools::findModule ( const std::string &  module)
private

Looks for the path for the module and returns it if it is found.

Parameters
moduleThe module to be searched for.
Returns
The path for the module.
Exceptions
MultipleInstacesFoundIf multiple instances of module are found.
FileNotFOundIf module is not found at all.

Definition at line 346 of file PluginTools.cc.

346  {
347  string path = "";
348  bool moduleFound = false;
349  for (MapIter mt = modules_.begin(); mt != modules_.end(); mt++) {
350 
351  const string fullPath = (*mt).first;
352  const string fileName = FileSystem::fileOfPath(fullPath);
353  if (module == fullPath ||
354  module == fileName ||
355  StringTools::endsWith(fullPath, std::string("/") + module)) {
356 
357  if (moduleFound) {
358  string method = "PluginTools::findModule()";
359  string message = "Multiple modules found";
361  __FILE__, __LINE__, method, message);
362  }
363 
364  path = (*mt).first;
365  moduleFound = true;
366  }
367  }
368 
369  if (!moduleFound) {
370  string method = "PluginTools::findModule()";
371  string message = "Module not found";
372  throw FileNotFound(__FILE__, __LINE__, method, message);
373  }
374 
375  return path;
376 }

References StringTools::endsWith(), FileSystem::fileOfPath(), and modules_.

Referenced by loadSym(), and unregisterModule().

Here is the call graph for this function:

◆ importSymbol() [1/2]

template<typename T >
void PluginTools::importSymbol ( const std::string &  symbolName,
T *&  target 
)

◆ importSymbol() [2/2]

template<typename T >
void PluginTools::importSymbol ( const std::string &  symbolName,
T *&  target,
const std::string &  module 
)

◆ loadSym()

void * PluginTools::loadSym ( const std::string &  symbolName,
const std::string &  module = "" 
)
private

Loads symbol from module.

If module is not given, then all modules are searched in order to find the symbol. Note that the search order of modules is not necessarily the same as the registration order!

Parameters
symbolNameThe symbol being loaded.
moduleThe module where symbol is loaded.
Returns
Pointer to loaded symbol.
Exceptions
MultipleInstancesFoundIf multiple instances of module are found.
DynamicLibraryExceptionIf dlsym() fails.
FileNotFoundIf module is not found.
SymbolNotFoundIf symbol to be loaded is not found.

Definition at line 271 of file PluginTools.cc.

271  {
272  string path = module;
273  if (module != "") {
274 
275  if (!FileSystem::isAbsolutePath(module)) {
276  try {
277  path = findModule(module);
278  } catch (const FileNotFound& f) {
279  // file was not found, so let's try to register it.
280  registerModule(module);
281  path = findModule(module);
282  }
283  } else {
284  if (!MapTools::containsKey(modules_, path)) {
285  registerModule(path);
286  }
287  }
288 
289  MapIter mt = modules_.find(path);
290  void* handle = (*mt).second;
291  const char* error = NULL;
292 
293  // clear possible old errors
294  dlerror();
295 
296  void* sym = dlsym(handle, symbolName.c_str());
297  if ((error = dlerror()) != NULL) {
298  if (sym == NULL) {
299  // it does not seem to be possible to separate the
300  // symbol not found error from other errors, thus this will
301  // probably always throw SymbolNotFound in case the symbol
302  // could not be loaded for any reason
303  string message = "Symbol not found: ";
304  message += symbolName;
305  throw SymbolNotFound(__FILE__, __LINE__, __func__, message);
306  } else {
308  __FILE__, __LINE__, __func__, error);
309  }
310  }
311 
312  return sym;
313 
314  } else {
315 
316  // seek all registered modules for the symbol and return the first
317  // one found
318  for (MapIter mt = modules_.begin(); mt != modules_.end(); mt++) {
319  void* handle = (*mt).second;
320  const char* error = NULL;
321  dlerror();
322  void* sym = dlsym(handle, symbolName.c_str());
323  if ((error = dlerror()) == NULL) {
324  return sym;
325  }
326  }
327 
328  // symbol was not found, exception is thrown
329  string method = "PluginTools::loadSym()";
330  string message = "Symbol not found";
331  throw SymbolNotFound(__FILE__, __LINE__, method, message);
332  }
333 
334  return NULL;
335 }

References __func__, MapTools::containsKey(), findModule(), FileSystem::isAbsolutePath(), modules_, and registerModule().

Here is the call graph for this function:

◆ operator=()

PluginTools& PluginTools::operator= ( const PluginTools )
private

Assignment not allowed.

◆ registerModule()

void PluginTools::registerModule ( const std::string &  module)

Registers a module in registry.

If module is not an absolute path, then it is searched from search paths added with addSearchPath() in the order of addition. First module found is used. If module already exists in the registry, it's not opened again. RTLD_LOCAL and RTLD_NOW flags are used by default when opening the module.

Parameters
moduleThe module to be registered.
Exceptions
FileNotFoundIf module is not found.
DynamicLibraryExceptionif dlopen() fails.

Definition at line 138 of file PluginTools.cc.

138  {
139  if (module.empty()) {
140  string method = "PluginTools::registerModule()";
141  string message = "Empty module file name.";
142  throw FileNotFound(__FILE__, __LINE__, method, message);
143  }
144 
146 
147  string path = module;
148  if (!FileSystem::isAbsolutePath(module)) {
149 
150  bool moduleFound = false;
151 
152  // module is not an absolute path
153  for (unsigned int i = 0; i < searchPaths_.size(); i++) {
154  path = searchPaths_[i] + DIR_SEP + module;
155  if (FileSystem::fileExists(path)) {
156  moduleFound = true;
157  break;
158  }
159  }
160 
161  if (!moduleFound) {
162  string method = "PluginTools::registerModule()";
163  string message = "Module not found";
164  throw FileNotFound(__FILE__, __LINE__, method, message);
165  }
166  }
167 
168  // multiple registrations are ignored
169  if (!MapTools::containsKey(modules_, path)) {
170 
171  void* handle = NULL;
172 
173  int flags = 0;
174  if (lazyResolution_) {
175  flags |= RTLD_LAZY;
176  } else {
177  flags |= RTLD_NOW;
178  }
179 
180  if (localResolution_) {
181  flags |= RTLD_LOCAL;
182  } else {
183  flags |= RTLD_GLOBAL;
184  }
185 
186  handle = dlopen(path.c_str(), flags);
187 
188  if (handle == NULL) {
189  string method = "PluginTools::registerModule()";
190  string message = dlerror();
191  throw DynamicLibraryException(__FILE__, __LINE__, method, message);
192  }
193 
194  modules_.insert(ValType(path, handle));
195  }
196 }

References MapTools::containsKey(), DIR_SEP, FileSystem::DIRECTORY_SEPARATOR, FileSystem::fileExists(), FileSystem::isAbsolutePath(), lazyResolution_, localResolution_, modules_, RTLD_LOCAL, and searchPaths_.

Referenced by CompiledSimulation::compileAndLoadFunction(), ProgramImageGenerator::createCompressor(), LLVMBackend::createPlugin(), GenerateProcessor::listICDecPluginParameters(), GenerateProcessorDialog::loadICDecoderGeneratorPlugin(), ProGe::ProGeUI::loadICDecoderGeneratorPlugin(), loadSym(), and CompiledSimController::reset().

Here is the call graph for this function:

◆ removeSearchPath()

void PluginTools::removeSearchPath ( const std::string &  searchPath)

Removes search path from search path list if it is found.

Parameters
searchPaththe search path to be removed.

Definition at line 110 of file PluginTools.cc.

110  {
112 }

References ContainerTools::removeValueIfExists(), and searchPaths_.

Here is the call graph for this function:

◆ unregisterAllModules()

void PluginTools::unregisterAllModules ( )

Unregisters all modules.

All modules are closed by using dlclose() and registry is emptied.

Exceptions
DynamicLibraryExceptionIf dlclose() fails.

Definition at line 236 of file PluginTools.cc.

236  {
237  MapIter mt;
238  for (mt = modules_.begin(); mt != modules_.end(); mt++) {
239  void* handle = (*mt).second;
240  std::string moduleName = (*mt).first;
241  dlclose(handle);
242  // Removing check. This is called on the global destructor
243  // stage and in some systems (FreeBSD) libraries are already
244  // unloaded by then which would cause this to fail unneccessarily.
245 // if (dlclose(handle) != 0) {
246 // string method = "PluginTools::unregisterAllModules()";
247 // string message = dlerror();
248 // throw DynamicLibraryException(__FILE__, __LINE__, method, message);
249 // }
250  }
251  modules_.clear();
252 }

References modules_.

Referenced by OperationBehaviorLoader::freeBehavior(), and ~PluginTools().

◆ unregisterModule()

void PluginTools::unregisterModule ( const std::string &  module)

A module is closed using dlclose() and it is removed from registry.

Parameters
moduleThe module to be unregistered.
Exceptions
FileNotFoundIf module is not found.
DynamicLibraryExceptionIf dlclose() fails.
MultipleInstancesFoundIf multiple modules are found.

Definition at line 207 of file PluginTools.cc.

207  {
208  string method = "PluginTools::unregisterModule()";
209  string path = module;
210  if (!FileSystem::isAbsolutePath(module)) {
211  path = findModule(module);
212  }
213 
214  MapIter mt = modules_.find(path);
215  if (mt == modules_.end()) {
216  string msg = "Module not found";
217  throw FileNotFound(__FILE__, __LINE__, method, msg);
218  }
219 
220  void* handle = (*mt).second;
221  modules_.erase(mt);
222  if (dlclose(handle) != 0) {
223  string message = dlerror();
224  throw DynamicLibraryException(__FILE__, __LINE__, method, message);
225  }
226 }

References findModule(), FileSystem::isAbsolutePath(), and modules_.

Here is the call graph for this function:

Member Data Documentation

◆ lazyResolution_

bool PluginTools::lazyResolution_
private

True if all undefined symbols should be resolved only when needed.

Definition at line 94 of file PluginTools.hh.

Referenced by registerModule().

◆ localResolution_

bool PluginTools::localResolution_
private

True if the symbols defined in the loaded library should be made available for symbol resolution of subsequently loaded libraries.

Definition at line 97 of file PluginTools.hh.

Referenced by registerModule().

◆ modules_

std::map<std::string, void*> PluginTools::modules_
private

Map containing opened module handles.

Definition at line 91 of file PluginTools.hh.

Referenced by findModule(), loadSym(), registerModule(), unregisterAllModules(), and unregisterModule().

◆ searchPaths_

std::vector<std::string> PluginTools::searchPaths_
private

Search paths of dynamic modules.

Definition at line 89 of file PluginTools.hh.

Referenced by addSearchPath(), clearSearchPaths(), registerModule(), and removeSearchPath().


The documentation for this class was generated from the following files:
StringTools::endsWith
static bool endsWith(const std::string &source, const std::string &searchString)
Definition: StringTools.cc:126
FileNotFound
Definition: Exception.hh:224
PluginTools::ValType
std::map< std::string, void * >::value_type ValType
Definition: PluginTools.hh:76
PluginTools::findModule
std::string findModule(const std::string &module)
Definition: PluginTools.cc:346
MultipleInstancesFound
Definition: Exception.hh:605
PluginTools::searchPaths_
std::vector< std::string > searchPaths_
Search paths of dynamic modules.
Definition: PluginTools.hh:89
FileSystem::fileOfPath
static std::string fileOfPath(const std::string pathName)
Definition: FileSystem.cc:101
PluginTools::localResolution_
bool localResolution_
True if the symbols defined in the loaded library should be made available for symbol resolution of s...
Definition: PluginTools.hh:97
SymbolNotFound
Definition: Exception.hh:623
ContainerTools::removeValueIfExists
static bool removeValueIfExists(ContainerType &aContainer, const ElementType &aKey)
__func__
#define __func__
Definition: Application.hh:67
PluginTools::registerModule
void registerModule(const std::string &module)
Definition: PluginTools.cc:138
FileSystem::DIRECTORY_SEPARATOR
static const std::string DIRECTORY_SEPARATOR
Definition: FileSystem.hh:189
DIR_SEP
const string DIR_SEP
Definition: GenerateBits.cc:71
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
PluginTools::modules_
std::map< std::string, void * > modules_
Map containing opened module handles.
Definition: PluginTools.hh:91
FileSystem::fileExists
static bool fileExists(const std::string fileName)
DynamicLibraryException
Definition: Exception.hh:588
FileSystem::isAbsolutePath
static bool isAbsolutePath(const std::string &pathName)
Definition: FileSystem.cc:234
PluginTools::MapIter
std::map< std::string, void * >::iterator MapIter
Definition: PluginTools.hh:75
RTLD_LOCAL
#define RTLD_LOCAL
Definition: PluginTools.cc:41
PluginTools::lazyResolution_
bool lazyResolution_
True if all undefined symbols should be resolved only when needed.
Definition: PluginTools.hh:94
PluginTools::unregisterAllModules
void unregisterAllModules()
Definition: PluginTools.cc:236