class_loader_core.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
32 
33 #include <boost/filesystem.hpp>
34 
35 #include <Poco/SharedLibrary.h>
36 
37 #include <cassert>
38 #include <cstddef>
39 #include <string>
40 #include <vector>
41 
42 namespace class_loader
43 {
44 namespace impl
45 {
46 
47 
48 // Global data
49 
50 boost::recursive_mutex & getLoadedLibraryVectorMutex()
51 {
52  static boost::recursive_mutex m;
53  return m;
54 }
55 
56 boost::recursive_mutex & getPluginBaseToFactoryMapMapMutex()
57 {
58  static boost::recursive_mutex m;
59  return m;
60 }
61 
63 {
64  static BaseToFactoryMapMap instance;
65  return instance;
66 }
67 
68 FactoryMap & getFactoryMapForBaseClass(const std::string & typeid_base_class_name)
69 {
71  std::string base_class_name = typeid_base_class_name;
72  if (factoryMapMap.find(base_class_name) == factoryMapMap.end()) {
73  factoryMapMap[base_class_name] = FactoryMap();
74  }
75 
76  return factoryMapMap[base_class_name];
77 }
78 
80 {
81  static MetaObjectVector instance;
82  return instance;
83 }
84 
86 {
87  static LibraryVector instance;
88  return instance;
89 }
90 
92 {
93  static std::string library_name;
94  return library_name;
95 }
96 
98 {
100 }
101 
102 void setCurrentlyLoadingLibraryName(const std::string & library_name)
103 {
104  std::string & library_name_ref = getCurrentlyLoadingLibraryNameReference();
105  library_name_ref = library_name;
106 }
107 
109 {
110  static ClassLoader * loader = nullptr;
111  return loader;
112 }
113 
115 {
117 }
118 
120 {
122  loader_ref = loader;
123 }
124 
126 {
129 }
130 
132 {
134 }
135 
137 {
139 }
140 
141 
142 // MetaObject search/insert/removal/query
143 
145 {
146  MetaObjectVector all_meta_objs;
147  for (auto & it : factories) {
148  all_meta_objs.push_back(it.second);
149  }
150  return all_meta_objs;
151 }
152 
154 {
155  boost::recursive_mutex::scoped_lock lock(getPluginBaseToFactoryMapMapMutex());
156 
157  MetaObjectVector all_meta_objs;
159  BaseToFactoryMapMap::iterator itr;
160 
161  for (auto & it : factory_map_map) {
162  MetaObjectVector objs = allMetaObjects(it.second);
163  all_meta_objs.insert(all_meta_objs.end(), objs.begin(), objs.end());
164  }
165  return all_meta_objs;
166 }
167 
170 {
171  MetaObjectVector filtered_objs;
172  for (auto & f : to_filter) {
173  if (f->isOwnedBy(owner)) {
174  filtered_objs.push_back(f);
175  }
176  }
177  return filtered_objs;
178 }
179 
182  const MetaObjectVector & to_filter, const std::string & library_path)
183 {
184  MetaObjectVector filtered_objs;
185  for (auto & f : to_filter) {
186  if (f->getAssociatedLibraryPath() == library_path) {
187  filtered_objs.push_back(f);
188  }
189  }
190  return filtered_objs;
191 }
192 
195 {
197 }
198 
200 allMetaObjectsForLibrary(const std::string & library_path)
201 {
203 }
204 
206 allMetaObjectsForLibraryOwnedBy(const std::string & library_path, const ClassLoader * owner)
207 {
208  return filterAllMetaObjectsOwnedBy(allMetaObjectsForLibrary(library_path), owner);
209 }
210 
212 {
213  CONSOLE_BRIDGE_logDebug(
214  "class_loader.impl: "
215  "Inserting MetaObject (class = %s, base_class = %s, ptr = %p) into graveyard",
216  meta_obj->className().c_str(), meta_obj->baseClassName().c_str(),
217  reinterpret_cast<void *>(meta_obj));
218  getMetaObjectGraveyard().push_back(meta_obj);
219 }
220 
222  const std::string & library_path, FactoryMap & factories, const ClassLoader * loader)
223 {
224  FactoryMap::iterator factory_itr = factories.begin();
225  while (factory_itr != factories.end()) {
226  AbstractMetaObjectBase * meta_obj = factory_itr->second;
227  if (meta_obj->getAssociatedLibraryPath() == library_path && meta_obj->isOwnedBy(loader)) {
228  meta_obj->removeOwningClassLoader(loader);
229  if (!meta_obj->isOwnedByAnybody()) {
230  FactoryMap::iterator factory_itr_copy = factory_itr;
231  factory_itr++;
232  // TODO(mikaelarguedas) fix this when branching out for melodic
233  // Note: map::erase does not return iterator like vector::erase does.
234  // Hence the ugliness of this code and a need for copy. Should be fixed in next C++ revision
235  factories.erase(factory_itr_copy);
236 
237  // Insert into graveyard
238  // We remove the metaobject from its factory map, but we don't destroy it...instead it
239  // saved to a "graveyard" to the side.
240  // This is due to our static global variable initialization problem that causes factories
241  // to not be registered when a library is closed and then reopened.
242  // This is because it's truly not closed due to the use of global symbol binding i.e.
243  // calling dlopen with RTLD_GLOBAL instead of RTLD_LOCAL.
244  // We require using the former as the which is required to support RTTI
246  } else {
247  ++factory_itr;
248  }
249  } else {
250  ++factory_itr;
251  }
252  }
253 }
254 
255 void destroyMetaObjectsForLibrary(const std::string & library_path, const ClassLoader * loader)
256 {
257  boost::recursive_mutex::scoped_lock lock(getPluginBaseToFactoryMapMapMutex());
258 
259  CONSOLE_BRIDGE_logDebug(
260  "class_loader.impl: "
261  "Removing MetaObjects associated with library %s and class loader %p from global "
262  "plugin-to-factorymap map.\n",
263  library_path.c_str(), reinterpret_cast<const void *>(loader));
264 
265  // We have to walk through all FactoryMaps to be sure
267  for (auto & it : factory_map_map) {
268  destroyMetaObjectsForLibrary(library_path, it.second, loader);
269  }
270 
271  CONSOLE_BRIDGE_logDebug("%s", "class_loader.impl: Metaobjects removed.");
272 }
273 
274 bool areThereAnyExistingMetaObjectsForLibrary(const std::string & library_path)
275 {
276  return allMetaObjectsForLibrary(library_path).size() > 0;
277 }
278 
279 // Loaded Library Vector manipulation
280 LibraryVector::iterator findLoadedLibrary(const std::string & library_path)
281 {
282  LibraryVector & open_libraries = getLoadedLibraryVector();
283  for (auto it = open_libraries.begin(); it != open_libraries.end(); ++it) {
284  if (it->first == library_path) {
285  return it;
286  }
287  }
288  return open_libraries.end();
289 }
290 
291 bool isLibraryLoadedByAnybody(const std::string & library_path)
292 {
293  boost::recursive_mutex::scoped_lock lock(getLoadedLibraryVectorMutex());
294 
295  LibraryVector & open_libraries = getLoadedLibraryVector();
296  LibraryVector::iterator itr = findLoadedLibrary(library_path);
297 
298  if (itr != open_libraries.end()) {
299  assert(itr->second->isLoaded() == true); // Ensure Poco actually thinks the library is loaded
300  return true;
301  } else {
302  return false;
303  }
304 }
305 
306 bool isLibraryLoaded(const std::string & library_path, ClassLoader * loader)
307 {
308  bool is_lib_loaded_by_anyone = isLibraryLoadedByAnybody(library_path);
309  size_t num_meta_objs_for_lib = allMetaObjectsForLibrary(library_path).size();
310  size_t num_meta_objs_for_lib_bound_to_loader =
311  allMetaObjectsForLibraryOwnedBy(library_path, loader).size();
312  bool are_meta_objs_bound_to_loader =
313  (0 == num_meta_objs_for_lib) ? true : (
314  num_meta_objs_for_lib_bound_to_loader <= num_meta_objs_for_lib);
315 
316  return is_lib_loaded_by_anyone && are_meta_objs_bound_to_loader;
317 }
318 
319 std::vector<std::string> getAllLibrariesUsedByClassLoader(const ClassLoader * loader)
320 {
321  MetaObjectVector all_loader_meta_objs = allMetaObjectsForClassLoader(loader);
322  std::vector<std::string> all_libs;
323  for (auto & meta_obj : all_loader_meta_objs) {
324  std::string lib_path = meta_obj->getAssociatedLibraryPath();
325  if (std::find(all_libs.begin(), all_libs.end(), lib_path) == all_libs.end()) {
326  all_libs.push_back(lib_path);
327  }
328  }
329  return all_libs;
330 }
331 
332 
333 // Implementation of Remaining Core plugin impl Functions
334 
336  const std::string & library_path, ClassLoader * loader)
337 {
338  MetaObjectVector all_meta_objs = allMetaObjectsForLibrary(library_path);
339  for (auto & meta_obj : all_meta_objs) {
340  CONSOLE_BRIDGE_logDebug(
341  "class_loader.impl: "
342  "Tagging existing MetaObject %p (base = %s, derived = %s) with "
343  "class loader %p (library path = %s).",
344  reinterpret_cast<void *>(meta_obj), meta_obj->baseClassName().c_str(),
345  meta_obj->className().c_str(),
346  reinterpret_cast<void *>(loader),
347  nullptr == loader ? loader->getLibraryPath().c_str() : "NULL");
348  meta_obj->addOwningClassLoader(loader);
349  }
350 }
351 
353  const std::string & library_path, ClassLoader * loader)
354 {
355  boost::recursive_mutex::scoped_lock b2fmm_lock(getPluginBaseToFactoryMapMapMutex());
357 
358  for (auto & obj : graveyard) {
359  if (obj->getAssociatedLibraryPath() == library_path) {
360  CONSOLE_BRIDGE_logDebug(
361  "class_loader.impl: "
362  "Resurrected factory metaobject from graveyard, class = %s, base_class = %s ptr = %p..."
363  "bound to ClassLoader %p (library path = %s)",
364  obj->className().c_str(), obj->baseClassName().c_str(), reinterpret_cast<void *>(obj),
365  reinterpret_cast<void *>(loader),
366  nullptr == loader ? loader->getLibraryPath().c_str() : "NULL");
367 
368  obj->addOwningClassLoader(loader);
369  assert(obj->typeidBaseClassName() != "UNSET");
370  FactoryMap & factory = getFactoryMapForBaseClass(obj->typeidBaseClassName());
371  factory[obj->className()] = obj;
372  }
373  }
374 }
375 
377  const std::string & library_path, ClassLoader * loader, bool delete_objs)
378 {
379  MetaObjectVector all_meta_objs = allMetaObjects();
380  // Note: Lock must happen after call to allMetaObjects as that will lock
381  boost::recursive_mutex::scoped_lock b2fmm_lock(getPluginBaseToFactoryMapMapMutex());
382 
384  MetaObjectVector::iterator itr = graveyard.begin();
385 
386  while (itr != graveyard.end()) {
387  AbstractMetaObjectBase * obj = *itr;
388  if (obj->getAssociatedLibraryPath() == library_path) {
389  CONSOLE_BRIDGE_logDebug(
390  "class_loader.impl: "
391  "Purging factory metaobject from graveyard, class = %s, base_class = %s ptr = %p.."
392  ".bound to ClassLoader %p (library path = %s)",
393  obj->className().c_str(), obj->baseClassName().c_str(), reinterpret_cast<void *>(obj),
394  reinterpret_cast<void *>(loader),
395  nullptr == loader ? loader->getLibraryPath().c_str() : "NULL");
396 
397  bool is_address_in_graveyard_same_as_global_factory_map =
398  std::find(all_meta_objs.begin(), all_meta_objs.end(), *itr) != all_meta_objs.end();
399  itr = graveyard.erase(itr);
400  if (delete_objs) {
401  if (is_address_in_graveyard_same_as_global_factory_map) {
402  CONSOLE_BRIDGE_logDebug("%s",
403  "class_loader.impl: "
404  "Newly created metaobject factory in global factory map map has same address as "
405  "one in graveyard -- metaobject has been purged from graveyard but not deleted.");
406  } else {
407  assert(hasANonPurePluginLibraryBeenOpened() == false);
408  CONSOLE_BRIDGE_logDebug(
409  "class_loader.impl: "
410  "Also destroying metaobject %p (class = %s, base_class = %s, library_path = %s) "
411  "in addition to purging it from graveyard.",
412  reinterpret_cast<void *>(obj), obj->className().c_str(), obj->baseClassName().c_str(),
413  obj->getAssociatedLibraryPath().c_str());
414 #ifndef _WIN32
415 #pragma GCC diagnostic push
416 #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
417 #endif
418  delete (obj); // Note: This is the only place where metaobjects can be destroyed
419 #ifndef _WIN32
420 #pragma GCC diagnostic pop
421 #endif
422  }
423  }
424  } else {
425  itr++;
426  }
427  }
428 }
429 
430 void loadLibrary(const std::string & library_path, ClassLoader * loader)
431 {
432  static boost::recursive_mutex loader_mutex;
433  CONSOLE_BRIDGE_logDebug(
434  "class_loader.impl: "
435  "Attempting to load library %s on behalf of ClassLoader handle %p...\n",
436  library_path.c_str(), reinterpret_cast<void *>(loader));
437  boost::recursive_mutex::scoped_lock loader_lock(loader_mutex);
438 
439  // If it's already open, just update existing metaobjects to have an additional owner.
440  if (isLibraryLoadedByAnybody(library_path)) {
441  boost::recursive_mutex::scoped_lock lock(getPluginBaseToFactoryMapMapMutex());
442  CONSOLE_BRIDGE_logDebug("%s",
443  "class_loader.impl: "
444  "Library already in memory, but binding existing MetaObjects to loader if necesesary.\n");
446  return;
447  }
448 
449  Poco::SharedLibrary * library_handle = nullptr;
450 
451  {
452  try {
454  setCurrentlyLoadingLibraryName(library_path);
455 
456  // Try to resolve symlinks in the library path, placed here just before load such that all current caching
457  // logic etc still works, the actual poco object's path doesn't seem to be used anywhere.
458  boost::system::error_code error_code;
459  const auto absolute_library_path = boost::filesystem::canonical(library_path, error_code);
460 
461  auto library_path_to_load = library_path;
462  if (error_code.value() == boost::system::errc::success) {
463  library_path_to_load = absolute_library_path.string();
464  }
465 
466  library_handle = new Poco::SharedLibrary(library_path_to_load);
467  } catch (const Poco::LibraryLoadException & e) {
471  "Could not load library (Poco exception = " + std::string(e.message()) + ")");
472  } catch (const Poco::LibraryAlreadyLoadedException & e) {
476  "Library already loaded (Poco exception = " + std::string(e.message()) + ")");
477  } catch (const Poco::NotFoundException & e) {
481  "Library not found (Poco exception = " + std::string(e.message()) + ")");
482  }
483 
486  }
487 
488  assert(library_handle != nullptr);
489  CONSOLE_BRIDGE_logDebug(
490  "class_loader.impl: "
491  "Successfully loaded library %s into memory (Poco::SharedLibrary handle = %p).",
492  library_path.c_str(), reinterpret_cast<void *>(library_handle));
493 
494  // Graveyard scenario
495  size_t num_lib_objs = allMetaObjectsForLibrary(library_path).size();
496  if (0 == num_lib_objs) {
497  CONSOLE_BRIDGE_logDebug(
498  "class_loader.impl: "
499  "Though the library %s was just loaded, it seems no factory metaobjects were registered. "
500  "Checking factory graveyard for previously loaded metaobjects...",
501  library_path.c_str());
503  // Note: The 'false' indicates we don't want to invoke delete on the metaobject
504  purgeGraveyardOfMetaobjects(library_path, loader, false);
505  } else {
506  CONSOLE_BRIDGE_logDebug(
507  "class_loader.impl: "
508  "Library %s generated new factory metaobjects on load. "
509  "Destroying graveyarded objects from previous loads...",
510  library_path.c_str());
511  purgeGraveyardOfMetaobjects(library_path, loader, true);
512  }
513 
514  // Insert library into global loaded library vector
515  boost::recursive_mutex::scoped_lock llv_lock(getLoadedLibraryVectorMutex());
516  LibraryVector & open_libraries = getLoadedLibraryVector();
517  // Note: Poco::SharedLibrary automatically calls load() when library passed to constructor
518  open_libraries.push_back(LibraryPair(library_path, library_handle));
519 }
520 
521 void unloadLibrary(const std::string & library_path, ClassLoader * loader)
522 {
524  CONSOLE_BRIDGE_logDebug(
525  "class_loader.impl: "
526  "Cannot unload %s or ANY other library as a non-pure plugin library was opened. "
527  "As class_loader has no idea which libraries class factories were exported from, "
528  "it can safely close any library without potentially unlinking symbols that are still "
529  "actively being used. "
530  "You must refactor your plugin libraries to be made exclusively of plugins "
531  "in order for this error to stop happening.",
532  library_path.c_str());
533  } else {
534  CONSOLE_BRIDGE_logDebug(
535  "class_loader.impl: "
536  "Unloading library %s on behalf of ClassLoader %p...",
537  library_path.c_str(), reinterpret_cast<void *>(loader));
538  boost::recursive_mutex::scoped_lock lock(getLoadedLibraryVectorMutex());
539  LibraryVector & open_libraries = getLoadedLibraryVector();
540  LibraryVector::iterator itr = findLoadedLibrary(library_path);
541  if (itr != open_libraries.end()) {
542  Poco::SharedLibrary * library = itr->second;
543  std::string library_path = itr->first;
544  try {
545  destroyMetaObjectsForLibrary(library_path, loader);
546 
547  // Remove from loaded library list as well if no more factories associated with said library
548  if (!areThereAnyExistingMetaObjectsForLibrary(library_path)) {
549  CONSOLE_BRIDGE_logDebug(
550  "class_loader.impl: "
551  "There are no more MetaObjects left for %s so unloading library and "
552  "removing from loaded library vector.\n",
553  library_path.c_str());
554  library->unload();
555  assert(library->isLoaded() == false);
556  delete (library);
557  itr = open_libraries.erase(itr);
558  } else {
559  CONSOLE_BRIDGE_logDebug(
560  "class_loader.impl: "
561  "MetaObjects still remain in memory meaning other ClassLoaders are still using library"
562  ", keeping library %s open.",
563  library_path.c_str());
564  }
565  return;
566  } catch (const Poco::RuntimeException & e) {
567  delete (library);
569  "Caught a poco exception while unloading library " + library_path + ": " + e.message());
570  }
571  }
573  "Attempt to unload library that class_loader is unaware of: " + library_path);
574  }
575 }
576 
577 
578 // Other
579 
581 {
582  printf("*******************************************************************************\n");
583  printf("***** class_loader impl DEBUG INFORMATION *****\n");
584  printf("*******************************************************************************\n");
585 
586  printf("OPEN LIBRARIES IN MEMORY:\n");
587  printf("--------------------------------------------------------------------------------\n");
588  boost::recursive_mutex::scoped_lock lock(getLoadedLibraryVectorMutex());
590  for (size_t c = 0; c < libs.size(); c++) {
591  printf(
592  "Open library %zu = %s (Poco SharedLibrary handle = %p)\n",
593  c, (libs.at(c)).first.c_str(), reinterpret_cast<void *>((libs.at(c)).second));
594  }
595 
596  printf("METAOBJECTS (i.e. FACTORIES) IN MEMORY:\n");
597  printf("--------------------------------------------------------------------------------\n");
598  MetaObjectVector meta_objs = allMetaObjects();
599  for (size_t c = 0; c < meta_objs.size(); c++) {
600  AbstractMetaObjectBase * obj = meta_objs.at(c);
601  printf("Metaobject %zu (ptr = %p):\n TypeId = %s\n Associated Library = %s\n",
602  c,
603  reinterpret_cast<void *>(obj),
604  (typeid(*obj).name()),
605  obj->getAssociatedLibraryPath().c_str());
606 
608  for (size_t i = 0; i < loaders.size(); i++) {
609  printf(" Associated Loader %zu = %p\n", i, reinterpret_cast<void *>(loaders.at(i)));
610  }
611  printf("--------------------------------------------------------------------------------\n");
612  }
613 
614  printf("********************************** END DEBUG **********************************\n");
615  printf("*******************************************************************************\n\n");
616 }
617 
618 
619 } // namespace impl
620 } // namespace class_loader
class_loader::impl::loadLibrary
CLASS_LOADER_PUBLIC void loadLibrary(const std::string &library_path, ClassLoader *loader)
Loads a library into memory if it has not already been done so. Attempting to load an already loaded ...
Definition: class_loader_core.cpp:430
class_loader::impl::LibraryPair
std::pair< LibraryPath, Poco::SharedLibrary * > LibraryPair
Definition: class_loader_core.hpp:72
class_loader::impl::allMetaObjectsForLibrary
MetaObjectVector allMetaObjectsForLibrary(const std::string &library_path)
Definition: class_loader_core.cpp:200
class_loader::impl::AbstractMetaObjectBase::getAssociatedLibraryPath
std::string getAssociatedLibraryPath()
Gets the path to the library associated with this factory.
Definition: meta_object.cpp:76
class_loader::impl::allMetaObjectsForClassLoader
MetaObjectVector allMetaObjectsForClassLoader(const ClassLoader *owner)
Definition: class_loader_core.cpp:194
class_loader::impl::AbstractMetaObjectBase::className
std::string className() const
Gets the literal name of the class.
Definition: meta_object.cpp:61
class_loader::LibraryLoadException
An exception class thrown when class_loader is unable to load a runtime library.
Definition: exceptions.hpp:57
class_loader
Definition: class_loader.hpp:50
class_loader::impl::AbstractMetaObjectBase
A base class for MetaObjects that excludes a polymorphic type parameter. Subclasses are class templat...
Definition: meta_object.hpp:59
class_loader::impl::getFactoryMapForBaseClass
CLASS_LOADER_PUBLIC FactoryMap & getFactoryMapForBaseClass(const std::string &typeid_base_class_name)
This function extracts a reference to the FactoryMap for appropriate base class out of the global plu...
Definition: class_loader_core.cpp:68
class_loader::impl::getCurrentlyActiveClassLoaderReference
ClassLoader *& getCurrentlyActiveClassLoaderReference()
Definition: class_loader_core.cpp:108
class_loader::impl::AbstractMetaObjectBase::isOwnedByAnybody
bool isOwnedByAnybody()
Indicates if the factory is within the usable scope of any ClassLoader.
Definition: meta_object.cpp:110
class_loader::impl::LibraryVector
std::vector< LibraryPair > LibraryVector
Definition: class_loader_core.hpp:73
class_loader_core.hpp
class_loader::impl::getCurrentlyLoadingLibraryName
CLASS_LOADER_PUBLIC std::string getCurrentlyLoadingLibraryName()
When a library is being loaded, in order for factories to know which library they are being associate...
Definition: class_loader_core.cpp:97
class_loader::impl::MetaObjectVector
std::vector< AbstractMetaObjectBase * > MetaObjectVector
Definition: class_loader_core.hpp:74
class_loader::impl::allMetaObjectsForLibraryOwnedBy
MetaObjectVector allMetaObjectsForLibraryOwnedBy(const std::string &library_path, const ClassLoader *owner)
Definition: class_loader_core.cpp:206
class_loader::impl::getGlobalPluginBaseToFactoryMapMap
CLASS_LOADER_PUBLIC BaseToFactoryMapMap & getGlobalPluginBaseToFactoryMapMap()
Gets a handle to a global data structure that holds a map of base class names (Base class describes p...
Definition: class_loader_core.cpp:62
class_loader::impl::getPluginBaseToFactoryMapMapMutex
CLASS_LOADER_PUBLIC boost::recursive_mutex & getPluginBaseToFactoryMapMapMutex()
Definition: class_loader_core.cpp:56
class_loader::impl::hasANonPurePluginLibraryBeenOpened
CLASS_LOADER_PUBLIC bool hasANonPurePluginLibraryBeenOpened()
Indicates if a library containing more than just plugins has been opened by the running process.
Definition: class_loader_core.cpp:131
class_loader::impl::filterAllMetaObjectsAssociatedWithLibrary
MetaObjectVector filterAllMetaObjectsAssociatedWithLibrary(const MetaObjectVector &to_filter, const std::string &library_path)
Definition: class_loader_core.cpp:181
class_loader::impl::AbstractMetaObjectBase::getAssociatedClassLoaders
ClassLoaderVector getAssociatedClassLoaders()
Definition: meta_object.cpp:115
class_loader::impl::AbstractMetaObjectBase::isOwnedBy
bool isOwnedBy(const ClassLoader *loader)
Indicates if the factory is within the usable scope of a ClassLoader.
Definition: meta_object.cpp:103
class_loader::impl::isLibraryLoadedByAnybody
CLASS_LOADER_PUBLIC bool isLibraryLoadedByAnybody(const std::string &library_path)
Indicates if passed library has been loaded by ANY ClassLoader.
Definition: class_loader_core.cpp:291
class_loader::impl::insertMetaObjectIntoGraveyard
void insertMetaObjectIntoGraveyard(AbstractMetaObjectBase *meta_obj)
Definition: class_loader_core.cpp:211
class_loader::impl::getCurrentlyActiveClassLoader
CLASS_LOADER_PUBLIC ClassLoader * getCurrentlyActiveClassLoader()
Gets the ClassLoader currently in scope which used when a library is being loaded.
Definition: class_loader_core.cpp:114
class_loader::impl::getCurrentlyLoadingLibraryNameReference
std::string & getCurrentlyLoadingLibraryNameReference()
Definition: class_loader_core.cpp:91
class_loader::impl::AbstractMetaObjectBase::removeOwningClassLoader
void removeOwningClassLoader(const ClassLoader *loader)
Removes a ClassLoader that is an owner of this factory.
Definition: meta_object.cpp:94
class_loader::impl::hasANonPurePluginLibraryBeenOpenedReference
bool & hasANonPurePluginLibraryBeenOpenedReference()
Definition: class_loader_core.cpp:125
class_loader::impl::allMetaObjects
MetaObjectVector allMetaObjects(const FactoryMap &factories)
Definition: class_loader_core.cpp:144
class_loader.hpp
class_loader::ClassLoader
This class allows loading and unloading of dynamically linked libraries which contain class definitio...
Definition: class_loader.hpp:78
class_loader::impl::setCurrentlyLoadingLibraryName
CLASS_LOADER_PUBLIC void setCurrentlyLoadingLibraryName(const std::string &library_name)
When a library is being loaded, in order for factories to know which library they are being associate...
Definition: class_loader_core.cpp:102
class_loader::impl::getLoadedLibraryVectorMutex
CLASS_LOADER_PUBLIC boost::recursive_mutex & getLoadedLibraryVectorMutex()
To provide thread safety, all exposed plugin functions can only be run serially by multiple threads....
Definition: class_loader_core.cpp:50
class_loader::impl::isLibraryLoaded
CLASS_LOADER_PUBLIC bool isLibraryLoaded(const std::string &library_path, ClassLoader *loader)
Indicates if passed library loaded within scope of a ClassLoader. The library maybe loaded in memory,...
Definition: class_loader_core.cpp:306
class_loader::impl::filterAllMetaObjectsOwnedBy
MetaObjectVector filterAllMetaObjectsOwnedBy(const MetaObjectVector &to_filter, const ClassLoader *owner)
Definition: class_loader_core.cpp:169
class_loader::impl::ClassLoaderVector
std::vector< class_loader::ClassLoader * > ClassLoaderVector
Definition: meta_object.hpp:53
class_loader::impl::revivePreviouslyCreateMetaobjectsFromGraveyard
void revivePreviouslyCreateMetaobjectsFromGraveyard(const std::string &library_path, ClassLoader *loader)
Definition: class_loader_core.cpp:352
class_loader::impl::getMetaObjectGraveyard
MetaObjectVector & getMetaObjectGraveyard()
Definition: class_loader_core.cpp:79
class_loader::impl::AbstractMetaObjectBase::baseClassName
std::string baseClassName() const
gets the base class for the class this factory represents
Definition: meta_object.cpp:66
class_loader::impl::getLoadedLibraryVector
CLASS_LOADER_PUBLIC LibraryVector & getLoadedLibraryVector()
Gets a handle to a list of open libraries in the form of LibraryPairs which encode the library path+n...
Definition: class_loader_core.cpp:85
class_loader::impl::findLoadedLibrary
LibraryVector::iterator findLoadedLibrary(const std::string &library_path)
Definition: class_loader_core.cpp:280
class_loader::impl::areThereAnyExistingMetaObjectsForLibrary
bool areThereAnyExistingMetaObjectsForLibrary(const std::string &library_path)
Definition: class_loader_core.cpp:274
class_loader::impl::BaseToFactoryMapMap
std::map< BaseClassName, FactoryMap > BaseToFactoryMapMap
Definition: class_loader_core.hpp:71
class_loader::impl::getAllLibrariesUsedByClassLoader
CLASS_LOADER_PUBLIC std::vector< std::string > getAllLibrariesUsedByClassLoader(const ClassLoader *loader)
This function returns the names of all libraries in use by a given class loader.
Definition: class_loader_core.cpp:319
class_loader::impl::purgeGraveyardOfMetaobjects
void purgeGraveyardOfMetaobjects(const std::string &library_path, ClassLoader *loader, bool delete_objs)
Definition: class_loader_core.cpp:376
class_loader::ClassLoader::getLibraryPath
CLASS_LOADER_PUBLIC std::string getLibraryPath()
Gets the full-qualified path and name of the library associated with this class loader.
Definition: class_loader.hpp:115
class_loader::impl::destroyMetaObjectsForLibrary
void destroyMetaObjectsForLibrary(const std::string &library_path, FactoryMap &factories, const ClassLoader *loader)
Definition: class_loader_core.cpp:221
class_loader::impl::FactoryMap
std::map< ClassName, impl::AbstractMetaObjectBase * > FactoryMap
Definition: class_loader_core.hpp:70
class_loader::impl::addClassLoaderOwnerForAllExistingMetaObjectsForLibrary
void addClassLoaderOwnerForAllExistingMetaObjectsForLibrary(const std::string &library_path, ClassLoader *loader)
Definition: class_loader_core.cpp:335
class_loader::impl::unloadLibrary
CLASS_LOADER_PUBLIC void unloadLibrary(const std::string &library_path, ClassLoader *loader)
Unloads a library if it loaded in memory and cleans up its corresponding class factories....
Definition: class_loader_core.cpp:521
class_loader::LibraryUnloadException
An exception class thrown when class_loader is unable to unload a runtime library.
Definition: exceptions.hpp:69
class_loader::impl::printDebugInfoToScreen
CLASS_LOADER_PUBLIC void printDebugInfoToScreen()
Definition: class_loader_core.cpp:580
class_loader::impl::setCurrentlyActiveClassLoader
CLASS_LOADER_PUBLIC void setCurrentlyActiveClassLoader(ClassLoader *loader)
Sets the ClassLoader currently in scope which used when a library is being loaded.
Definition: class_loader_core.cpp:119


class_loader
Author(s): Mirza Shah, Steven! Ragnarök
autogenerated on Fri Jan 12 2024 04:01:32