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


class_loader
Author(s): Mirza Shah
autogenerated on Thu Dec 7 2017 03:43:35