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 <Poco/SharedLibrary.h>
34 
35 #include <cassert>
36 #include <cstddef>
37 #include <string>
38 #include <vector>
39 
40 namespace class_loader
41 {
42 namespace impl
43 {
44 
45 
46 // Global data
47 
48 boost::recursive_mutex & getLoadedLibraryVectorMutex()
49 {
50  static boost::recursive_mutex m;
51  return m;
52 }
53 
54 boost::recursive_mutex & getPluginBaseToFactoryMapMapMutex()
55 {
56  static boost::recursive_mutex m;
57  return m;
58 }
59 
61 {
62  static BaseToFactoryMapMap instance;
63  return instance;
64 }
65 
66 FactoryMap & getFactoryMapForBaseClass(const std::string & typeid_base_class_name)
67 {
69  std::string base_class_name = typeid_base_class_name;
70  if (factoryMapMap.find(base_class_name) == factoryMapMap.end()) {
71  factoryMapMap[base_class_name] = FactoryMap();
72  }
73 
74  return factoryMapMap[base_class_name];
75 }
76 
78 {
79  static MetaObjectVector instance;
80  return instance;
81 }
82 
84 {
85  static LibraryVector instance;
86  return instance;
87 }
88 
90 {
91  static std::string library_name;
92  return library_name;
93 }
94 
96 {
98 }
99 
100 void setCurrentlyLoadingLibraryName(const std::string & library_name)
101 {
102  std::string & library_name_ref = getCurrentlyLoadingLibraryNameReference();
103  library_name_ref = library_name;
104 }
105 
107 {
108  static ClassLoader * loader = nullptr;
109  return loader;
110 }
111 
113 {
115 }
116 
118 {
120  loader_ref = loader;
121 }
122 
124 {
127 }
128 
130 {
132 }
133 
135 {
137 }
138 
139 
140 // MetaObject search/insert/removal/query
141 
143 {
144  MetaObjectVector all_meta_objs;
145  for (auto & it : factories) {
146  all_meta_objs.push_back(it.second);
147  }
148  return all_meta_objs;
149 }
150 
152 {
153  boost::recursive_mutex::scoped_lock lock(getPluginBaseToFactoryMapMapMutex());
154 
155  MetaObjectVector all_meta_objs;
157  BaseToFactoryMapMap::iterator itr;
158 
159  for (auto & it : factory_map_map) {
160  MetaObjectVector objs = allMetaObjects(it.second);
161  all_meta_objs.insert(all_meta_objs.end(), objs.begin(), objs.end());
162  }
163  return all_meta_objs;
164 }
165 
168 {
169  MetaObjectVector filtered_objs;
170  for (auto & f : to_filter) {
171  if (f->isOwnedBy(owner)) {
172  filtered_objs.push_back(f);
173  }
174  }
175  return filtered_objs;
176 }
177 
180  const MetaObjectVector & to_filter, const std::string & library_path)
181 {
182  MetaObjectVector filtered_objs;
183  for (auto & f : to_filter) {
184  if (f->getAssociatedLibraryPath() == library_path) {
185  filtered_objs.push_back(f);
186  }
187  }
188  return filtered_objs;
189 }
190 
193 {
195 }
196 
198 allMetaObjectsForLibrary(const std::string & library_path)
199 {
201 }
202 
204 allMetaObjectsForLibraryOwnedBy(const std::string & library_path, const ClassLoader * owner)
205 {
206  return filterAllMetaObjectsOwnedBy(allMetaObjectsForLibrary(library_path), owner);
207 }
208 
210 {
211  CONSOLE_BRIDGE_logDebug(
212  "class_loader.impl: "
213  "Inserting MetaObject (class = %s, base_class = %s, ptr = %p) into graveyard",
214  meta_obj->className().c_str(), meta_obj->baseClassName().c_str(),
215  reinterpret_cast<void *>(meta_obj));
216  getMetaObjectGraveyard().push_back(meta_obj);
217 }
218 
220  const std::string & library_path, FactoryMap & factories, const ClassLoader * loader)
221 {
222  FactoryMap::iterator factory_itr = factories.begin();
223  while (factory_itr != factories.end()) {
224  AbstractMetaObjectBase * meta_obj = factory_itr->second;
225  if (meta_obj->getAssociatedLibraryPath() == library_path && meta_obj->isOwnedBy(loader)) {
226  meta_obj->removeOwningClassLoader(loader);
227  if (!meta_obj->isOwnedByAnybody()) {
228  FactoryMap::iterator factory_itr_copy = factory_itr;
229  factory_itr++;
230  // TODO(mikaelarguedas) fix this when branching out for melodic
231  // Note: map::erase does not return iterator like vector::erase does.
232  // Hence the ugliness of this code and a need for copy. Should be fixed in next C++ revision
233  factories.erase(factory_itr_copy);
234 
235  // Insert into graveyard
236  // We remove the metaobject from its factory map, but we don't destroy it...instead it
237  // saved to a "graveyard" to the side.
238  // This is due to our static global variable initialization problem that causes factories
239  // to not be registered when a library is closed and then reopened.
240  // This is because it's truly not closed due to the use of global symbol binding i.e.
241  // calling dlopen with RTLD_GLOBAL instead of RTLD_LOCAL.
242  // We require using the former as the which is required to support RTTI
244  } else {
245  ++factory_itr;
246  }
247  } else {
248  ++factory_itr;
249  }
250  }
251 }
252 
253 void destroyMetaObjectsForLibrary(const std::string & library_path, const ClassLoader * loader)
254 {
255  boost::recursive_mutex::scoped_lock lock(getPluginBaseToFactoryMapMapMutex());
256 
257  CONSOLE_BRIDGE_logDebug(
258  "class_loader.impl: "
259  "Removing MetaObjects associated with library %s and class loader %p from global "
260  "plugin-to-factorymap map.\n",
261  library_path.c_str(), reinterpret_cast<const void *>(loader));
262 
263  // We have to walk through all FactoryMaps to be sure
265  for (auto & it : factory_map_map) {
266  destroyMetaObjectsForLibrary(library_path, it.second, loader);
267  }
268 
269  CONSOLE_BRIDGE_logDebug("%s", "class_loader.impl: Metaobjects removed.");
270 }
271 
272 bool areThereAnyExistingMetaObjectsForLibrary(const std::string & library_path)
273 {
274  return allMetaObjectsForLibrary(library_path).size() > 0;
275 }
276 
277 // Loaded Library Vector manipulation
278 LibraryVector::iterator findLoadedLibrary(const std::string & library_path)
279 {
280  LibraryVector & open_libraries = getLoadedLibraryVector();
281  for (auto it = open_libraries.begin(); it != open_libraries.end(); ++it) {
282  if (it->first == library_path) {
283  return it;
284  }
285  }
286  return open_libraries.end();
287 }
288 
289 bool isLibraryLoadedByAnybody(const std::string & library_path)
290 {
291  boost::recursive_mutex::scoped_lock lock(getLoadedLibraryVectorMutex());
292 
293  LibraryVector & open_libraries = getLoadedLibraryVector();
294  LibraryVector::iterator itr = findLoadedLibrary(library_path);
295 
296  if (itr != open_libraries.end()) {
297  assert(itr->second->isLoaded() == true); // Ensure Poco actually thinks the library is loaded
298  return true;
299  } else {
300  return false;
301  }
302 }
303 
304 bool isLibraryLoaded(const std::string & library_path, ClassLoader * loader)
305 {
306  bool is_lib_loaded_by_anyone = isLibraryLoadedByAnybody(library_path);
307  size_t num_meta_objs_for_lib = allMetaObjectsForLibrary(library_path).size();
308  size_t num_meta_objs_for_lib_bound_to_loader =
309  allMetaObjectsForLibraryOwnedBy(library_path, loader).size();
310  bool are_meta_objs_bound_to_loader =
311  (0 == num_meta_objs_for_lib) ? true : (
312  num_meta_objs_for_lib_bound_to_loader <= num_meta_objs_for_lib);
313 
314  return is_lib_loaded_by_anyone && are_meta_objs_bound_to_loader;
315 }
316 
317 std::vector<std::string> getAllLibrariesUsedByClassLoader(const ClassLoader * loader)
318 {
319  MetaObjectVector all_loader_meta_objs = allMetaObjectsForClassLoader(loader);
320  std::vector<std::string> all_libs;
321  for (auto & meta_obj : all_loader_meta_objs) {
322  std::string lib_path = meta_obj->getAssociatedLibraryPath();
323  if (std::find(all_libs.begin(), all_libs.end(), lib_path) == all_libs.end()) {
324  all_libs.push_back(lib_path);
325  }
326  }
327  return all_libs;
328 }
329 
330 
331 // Implementation of Remaining Core plugin impl Functions
332 
334  const std::string & library_path, ClassLoader * loader)
335 {
336  MetaObjectVector all_meta_objs = allMetaObjectsForLibrary(library_path);
337  for (auto & meta_obj : all_meta_objs) {
338  CONSOLE_BRIDGE_logDebug(
339  "class_loader.impl: "
340  "Tagging existing MetaObject %p (base = %s, derived = %s) with "
341  "class loader %p (library path = %s).",
342  reinterpret_cast<void *>(meta_obj), meta_obj->baseClassName().c_str(),
343  meta_obj->className().c_str(),
344  reinterpret_cast<void *>(loader),
345  nullptr == loader ? loader->getLibraryPath().c_str() : "NULL");
346  meta_obj->addOwningClassLoader(loader);
347  }
348 }
349 
351  const std::string & library_path, ClassLoader * loader)
352 {
353  boost::recursive_mutex::scoped_lock b2fmm_lock(getPluginBaseToFactoryMapMapMutex());
355 
356  for (auto & obj : graveyard) {
357  if (obj->getAssociatedLibraryPath() == library_path) {
358  CONSOLE_BRIDGE_logDebug(
359  "class_loader.impl: "
360  "Resurrected factory metaobject from graveyard, class = %s, base_class = %s ptr = %p..."
361  "bound to ClassLoader %p (library path = %s)",
362  obj->className().c_str(), obj->baseClassName().c_str(), reinterpret_cast<void *>(obj),
363  reinterpret_cast<void *>(loader),
364  nullptr == loader ? loader->getLibraryPath().c_str() : "NULL");
365 
366  obj->addOwningClassLoader(loader);
367  assert(obj->typeidBaseClassName() != "UNSET");
368  FactoryMap & factory = getFactoryMapForBaseClass(obj->typeidBaseClassName());
369  factory[obj->className()] = obj;
370  }
371  }
372 }
373 
375  const std::string & library_path, ClassLoader * loader, bool delete_objs)
376 {
377  MetaObjectVector all_meta_objs = allMetaObjects();
378  // Note: Lock must happen after call to allMetaObjects as that will lock
379  boost::recursive_mutex::scoped_lock b2fmm_lock(getPluginBaseToFactoryMapMapMutex());
380 
382  MetaObjectVector::iterator itr = graveyard.begin();
383 
384  while (itr != graveyard.end()) {
385  AbstractMetaObjectBase * obj = *itr;
386  if (obj->getAssociatedLibraryPath() == library_path) {
387  CONSOLE_BRIDGE_logDebug(
388  "class_loader.impl: "
389  "Purging factory metaobject from graveyard, class = %s, base_class = %s ptr = %p.."
390  ".bound to ClassLoader %p (library path = %s)",
391  obj->className().c_str(), obj->baseClassName().c_str(), reinterpret_cast<void *>(obj),
392  reinterpret_cast<void *>(loader),
393  nullptr == loader ? loader->getLibraryPath().c_str() : "NULL");
394 
395  bool is_address_in_graveyard_same_as_global_factory_map =
396  std::find(all_meta_objs.begin(), all_meta_objs.end(), *itr) != all_meta_objs.end();
397  itr = graveyard.erase(itr);
398  if (delete_objs) {
399  if (is_address_in_graveyard_same_as_global_factory_map) {
400  CONSOLE_BRIDGE_logDebug("%s",
401  "class_loader.impl: "
402  "Newly created metaobject factory in global factory map map has same address as "
403  "one in graveyard -- metaobject has been purged from graveyard but not deleted.");
404  } else {
405  assert(hasANonPurePluginLibraryBeenOpened() == false);
406  CONSOLE_BRIDGE_logDebug(
407  "class_loader.impl: "
408  "Also destroying metaobject %p (class = %s, base_class = %s, library_path = %s) "
409  "in addition to purging it from graveyard.",
410  reinterpret_cast<void *>(obj), obj->className().c_str(), obj->baseClassName().c_str(),
411  obj->getAssociatedLibraryPath().c_str());
412 #ifndef _WIN32
413 #pragma GCC diagnostic push
414 #pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
415 #endif
416  delete (obj); // Note: This is the only place where metaobjects can be destroyed
417 #ifndef _WIN32
418 #pragma GCC diagnostic pop
419 #endif
420  }
421  }
422  } else {
423  itr++;
424  }
425  }
426 }
427 
428 void loadLibrary(const std::string & library_path, ClassLoader * loader)
429 {
430  static boost::recursive_mutex loader_mutex;
431  CONSOLE_BRIDGE_logDebug(
432  "class_loader.impl: "
433  "Attempting to load library %s on behalf of ClassLoader handle %p...\n",
434  library_path.c_str(), reinterpret_cast<void *>(loader));
435  boost::recursive_mutex::scoped_lock loader_lock(loader_mutex);
436 
437  // If it's already open, just update existing metaobjects to have an additional owner.
438  if (isLibraryLoadedByAnybody(library_path)) {
439  boost::recursive_mutex::scoped_lock lock(getPluginBaseToFactoryMapMapMutex());
440  CONSOLE_BRIDGE_logDebug("%s",
441  "class_loader.impl: "
442  "Library already in memory, but binding existing MetaObjects to loader if necesesary.\n");
444  return;
445  }
446 
447  Poco::SharedLibrary * library_handle = nullptr;
448 
449  {
450  try {
452  setCurrentlyLoadingLibraryName(library_path);
453  library_handle = new Poco::SharedLibrary(library_path);
454  } catch (const Poco::LibraryLoadException & e) {
458  "Could not load library (Poco exception = " + std::string(e.message()) + ")");
459  } catch (const Poco::LibraryAlreadyLoadedException & e) {
463  "Library already loaded (Poco exception = " + std::string(e.message()) + ")");
464  } catch (const Poco::NotFoundException & e) {
468  "Library not found (Poco exception = " + std::string(e.message()) + ")");
469  }
470 
473  }
474 
475  assert(library_handle != nullptr);
476  CONSOLE_BRIDGE_logDebug(
477  "class_loader.impl: "
478  "Successfully loaded library %s into memory (Poco::SharedLibrary handle = %p).",
479  library_path.c_str(), reinterpret_cast<void *>(library_handle));
480 
481  // Graveyard scenario
482  size_t num_lib_objs = allMetaObjectsForLibrary(library_path).size();
483  if (0 == num_lib_objs) {
484  CONSOLE_BRIDGE_logDebug(
485  "class_loader.impl: "
486  "Though the library %s was just loaded, it seems no factory metaobjects were registered. "
487  "Checking factory graveyard for previously loaded metaobjects...",
488  library_path.c_str());
490  // Note: The 'false' indicates we don't want to invoke delete on the metaobject
491  purgeGraveyardOfMetaobjects(library_path, loader, false);
492  } else {
493  CONSOLE_BRIDGE_logDebug(
494  "class_loader.impl: "
495  "Library %s generated new factory metaobjects on load. "
496  "Destroying graveyarded objects from previous loads...",
497  library_path.c_str());
498  purgeGraveyardOfMetaobjects(library_path, loader, true);
499  }
500 
501  // Insert library into global loaded library vector
502  boost::recursive_mutex::scoped_lock llv_lock(getLoadedLibraryVectorMutex());
503  LibraryVector & open_libraries = getLoadedLibraryVector();
504  // Note: Poco::SharedLibrary automatically calls load() when library passed to constructor
505  open_libraries.push_back(LibraryPair(library_path, library_handle));
506 }
507 
508 void unloadLibrary(const std::string & library_path, ClassLoader * loader)
509 {
511  CONSOLE_BRIDGE_logDebug(
512  "class_loader.impl: "
513  "Cannot unload %s or ANY other library as a non-pure plugin library was opened. "
514  "As class_loader has no idea which libraries class factories were exported from, "
515  "it can safely close any library without potentially unlinking symbols that are still "
516  "actively being used. "
517  "You must refactor your plugin libraries to be made exclusively of plugins "
518  "in order for this error to stop happening.",
519  library_path.c_str());
520  } else {
521  CONSOLE_BRIDGE_logDebug(
522  "class_loader.impl: "
523  "Unloading library %s on behalf of ClassLoader %p...",
524  library_path.c_str(), reinterpret_cast<void *>(loader));
525  boost::recursive_mutex::scoped_lock lock(getLoadedLibraryVectorMutex());
526  LibraryVector & open_libraries = getLoadedLibraryVector();
527  LibraryVector::iterator itr = findLoadedLibrary(library_path);
528  if (itr != open_libraries.end()) {
529  Poco::SharedLibrary * library = itr->second;
530  std::string library_path = itr->first;
531  try {
532  destroyMetaObjectsForLibrary(library_path, loader);
533 
534  // Remove from loaded library list as well if no more factories associated with said library
535  if (!areThereAnyExistingMetaObjectsForLibrary(library_path)) {
536  CONSOLE_BRIDGE_logDebug(
537  "class_loader.impl: "
538  "There are no more MetaObjects left for %s so unloading library and "
539  "removing from loaded library vector.\n",
540  library_path.c_str());
541  library->unload();
542  assert(library->isLoaded() == false);
543  delete (library);
544  itr = open_libraries.erase(itr);
545  } else {
546  CONSOLE_BRIDGE_logDebug(
547  "class_loader.impl: "
548  "MetaObjects still remain in memory meaning other ClassLoaders are still using library"
549  ", keeping library %s open.",
550  library_path.c_str());
551  }
552  return;
553  } catch (const Poco::RuntimeException & e) {
554  delete (library);
556  "Could not unload library (Poco exception = " + std::string(e.message()) + ")");
557  }
558  }
560  "Attempt to unload library that class_loader is unaware of.");
561  }
562 }
563 
564 
565 // Other
566 
568 {
569  printf("*******************************************************************************\n");
570  printf("***** class_loader impl DEBUG INFORMATION *****\n");
571  printf("*******************************************************************************\n");
572 
573  printf("OPEN LIBRARIES IN MEMORY:\n");
574  printf("--------------------------------------------------------------------------------\n");
575  boost::recursive_mutex::scoped_lock lock(getLoadedLibraryVectorMutex());
577  for (size_t c = 0; c < libs.size(); c++) {
578  printf(
579  "Open library %zu = %s (Poco SharedLibrary handle = %p)\n",
580  c, (libs.at(c)).first.c_str(), reinterpret_cast<void *>((libs.at(c)).second));
581  }
582 
583  printf("METAOBJECTS (i.e. FACTORIES) IN MEMORY:\n");
584  printf("--------------------------------------------------------------------------------\n");
585  MetaObjectVector meta_objs = allMetaObjects();
586  for (size_t c = 0; c < meta_objs.size(); c++) {
587  AbstractMetaObjectBase * obj = meta_objs.at(c);
588  printf("Metaobject %zu (ptr = %p):\n TypeId = %s\n Associated Library = %s\n",
589  c,
590  reinterpret_cast<void *>(obj),
591  (typeid(*obj).name()),
592  obj->getAssociatedLibraryPath().c_str());
593 
595  for (size_t i = 0; i < loaders.size(); i++) {
596  printf(" Associated Loader %zu = %p\n", i, reinterpret_cast<void *>(loaders.at(i)));
597  }
598  printf("--------------------------------------------------------------------------------\n");
599  }
600 
601  printf("********************************** END DEBUG **********************************\n");
602  printf("*******************************************************************************\n\n");
603 }
604 
605 
606 } // namespace impl
607 } // namespace class_loader
An exception class thrown when class_loader is unable to load a runtime library.
Definition: exceptions.hpp:57
std::string getAssociatedLibraryPath()
Gets the path to the library associated with this factory.
Definition: meta_object.cpp:76
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 ...
std::vector< class_loader::ClassLoader * > ClassLoaderVector
Definition: meta_object.hpp:53
MetaObjectVector allMetaObjectsForLibrary(const std::string &library_path)
CLASS_LOADER_PUBLIC ClassLoader * getCurrentlyActiveClassLoader()
Gets the ClassLoader currently in scope which used when a library is being loaded.
MetaObjectVector allMetaObjectsForLibraryOwnedBy(const std::string &library_path, const ClassLoader *owner)
A base class for MetaObjects that excludes a polymorphic type parameter. Subclasses are class templat...
Definition: meta_object.hpp:59
bool & hasANonPurePluginLibraryBeenOpenedReference()
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...
MetaObjectVector filterAllMetaObjectsAssociatedWithLibrary(const MetaObjectVector &to_filter, const std::string &library_path)
CLASS_LOADER_PUBLIC std::string getCurrentlyLoadingLibraryName()
When a library is being loaded, in order for factories to know which library they are being associate...
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. If it is not loaded, the function has no effect.
void addClassLoaderOwnerForAllExistingMetaObjectsForLibrary(const std::string &library_path, ClassLoader *loader)
CLASS_LOADER_PUBLIC bool hasANonPurePluginLibraryBeenOpened()
Indicates if a library containing more than just plugins has been opened by the running process...
This class allows loading and unloading of dynamically linked libraries which contain class definitio...
CLASS_LOADER_PUBLIC boost::recursive_mutex & getLoadedLibraryVectorMutex()
To provide thread safety, all exposed plugin functions can only be run serially by multiple threads...
std::pair< LibraryPath, Poco::SharedLibrary * > LibraryPair
CLASS_LOADER_PUBLIC boost::recursive_mutex & getPluginBaseToFactoryMapMapMutex()
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.
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...
std::string baseClassName() const
gets the base class for the class this factory represents
Definition: meta_object.cpp:66
MetaObjectVector filterAllMetaObjectsOwnedBy(const MetaObjectVector &to_filter, const ClassLoader *owner)
std::map< ClassName, impl::AbstractMetaObjectBase * > FactoryMap
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...
std::vector< LibraryPair > LibraryVector
std::string & getCurrentlyLoadingLibraryNameReference()
LibraryVector::iterator findLoadedLibrary(const std::string &library_path)
void insertMetaObjectIntoGraveyard(AbstractMetaObjectBase *meta_obj)
ClassLoader *& getCurrentlyActiveClassLoaderReference()
MetaObjectVector & getMetaObjectGraveyard()
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...
CLASS_LOADER_PUBLIC std::string getLibraryPath()
Gets the full-qualified path and name of the library associated with this class loader.
MetaObjectVector allMetaObjectsForClassLoader(const ClassLoader *owner)
void removeOwningClassLoader(const ClassLoader *loader)
Removes a ClassLoader that is an owner of this factory.
Definition: meta_object.cpp:94
std::map< BaseClassName, FactoryMap > BaseToFactoryMapMap
bool isOwnedByAnybody()
Indicates if the factory is within the usable scope of any ClassLoader.
void destroyMetaObjectsForLibrary(const std::string &library_path, FactoryMap &factories, const ClassLoader *loader)
std::vector< AbstractMetaObjectBase * > MetaObjectVector
void revivePreviouslyCreateMetaobjectsFromGraveyard(const std::string &library_path, ClassLoader *loader)
bool isOwnedBy(const ClassLoader *loader)
Indicates if the factory is within the usable scope of a ClassLoader.
MetaObjectVector allMetaObjects(const FactoryMap &factories)
std::string className() const
Gets the literal name of the class.
Definition: meta_object.cpp:61
void purgeGraveyardOfMetaobjects(const std::string &library_path, ClassLoader *loader, bool delete_objs)
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...
CLASS_LOADER_PUBLIC void setCurrentlyActiveClassLoader(ClassLoader *loader)
Sets the ClassLoader currently in scope which used when a library is being loaded.
CLASS_LOADER_PUBLIC bool isLibraryLoadedByAnybody(const std::string &library_path)
Indicates if passed library has been loaded by ANY ClassLoader.
CLASS_LOADER_PUBLIC void printDebugInfoToScreen()
bool areThereAnyExistingMetaObjectsForLibrary(const std::string &library_path)
An exception class thrown when class_loader is unable to unload a runtime library.
Definition: exceptions.hpp:69


class_loader
Author(s): Mirza Shah, Steven! Ragnarök
autogenerated on Mon Feb 28 2022 22:02:03