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


class_loader
Author(s): Mirza Shah
autogenerated on Mon Jun 10 2019 12:51:50