From 2de2fb4fe3aebe331205d1735dd2c0ecb28094df Mon Sep 17 00:00:00 2001 From: Robert Haschke Date: Sun, 3 Apr 2016 12:08:32 +0200 Subject: [PATCH 1/4] added MultiLibraryClassLoader unittest --- test/utest.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/test/utest.cpp b/test/utest.cpp index b24b172a..09ac7498 100644 --- a/test/utest.cpp +++ b/test/utest.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "base.h" #include @@ -297,8 +298,65 @@ TEST(ClassLoaderTest, loadRefCountingLazy) FAIL() << "Did not throw exception as expected.\n"; } + /*****************************************************************************/ +void testMultiClassLoader(bool lazy) +{ + try + { + class_loader::MultiLibraryClassLoader loader(lazy); + loader.loadLibrary(LIBRARY_1); + loader.loadLibrary(LIBRARY_2); + for (int i=0; i < 2; ++i) { + loader.createInstance("Cat")->saySomething(); + loader.createInstance("Dog")->saySomething(); + loader.createInstance("Robot")->saySomething(); + } + } + catch(class_loader::ClassLoaderException& e) + { + FAIL() << "ClassLoaderException: " << e.what() << "\n"; + } + + SUCCEED(); +} + +TEST(MultiClassLoaderTest, lazyLoad) +{ + testMultiClassLoader(true); +} +TEST(MultiClassLoaderTest, nonLazyLoad) +{ + testMultiClassLoader(false); +} +TEST(MultiClassLoaderTest, noWarningOnLazyLoad) +{ + try + { + boost::shared_ptr cat, dog, rob; + { + class_loader::MultiLibraryClassLoader loader(true); + loader.loadLibrary(LIBRARY_1); + loader.loadLibrary(LIBRARY_2); + + cat = loader.createInstance("Cat"); + dog = loader.createInstance("Dog"); + rob = loader.createInstance("Robot"); + } + cat->saySomething(); + dog->saySomething(); + rob->saySomething(); + } + catch(class_loader::ClassLoaderException& e) + { + FAIL() << "ClassLoaderException: " << e.what() << "\n"; + } + + SUCCEED(); +} + +/*****************************************************************************/ // Run all the tests that were declared with TEST() int main(int argc, char **argv){ From 8a816d7f2c118584df2ba25f266145e9314cfd02 Mon Sep 17 00:00:00 2001 From: Robert Haschke Date: Sun, 3 Apr 2016 16:39:51 +0200 Subject: [PATCH 2/4] extra utest: MultiClassLoaderTest.lazyLoad succeeds two times in a row? --- test/utest.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/utest.cpp b/test/utest.cpp index 09ac7498..a8ec03f6 100644 --- a/test/utest.cpp +++ b/test/utest.cpp @@ -326,6 +326,10 @@ TEST(MultiClassLoaderTest, lazyLoad) { testMultiClassLoader(true); } +TEST(MultiClassLoaderTest, lazyLoadSecondTime) +{ + testMultiClassLoader(true); +} TEST(MultiClassLoaderTest, nonLazyLoad) { testMultiClassLoader(false); From f6d8ccc3d9f7b283fc0fdd067935e2c0cbc042cc Mon Sep 17 00:00:00 2001 From: Robert Haschke Date: Sun, 3 Apr 2016 09:11:00 +0200 Subject: [PATCH 3/4] bugfix: enable on-demand loading/unloading with MultiClassLoader - enforce loading of library in loadLibrary(), otherwise we cannot know - don't unload libraries in destructor when on-demand-unloading is enabled --- include/class_loader/multi_library_class_loader.h | 4 ++++ src/multi_library_class_loader.cpp | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/class_loader/multi_library_class_loader.h b/include/class_loader/multi_library_class_loader.h index b7a5fe7b..17aa27e1 100644 --- a/include/class_loader/multi_library_class_loader.h +++ b/include/class_loader/multi_library_class_loader.h @@ -73,6 +73,8 @@ class MultiLibraryClassLoader for(unsigned int c = 0; c < active_loaders.size(); c++) { ClassLoader* current = active_loaders.at(c); + if (!current->isLibraryLoaded()) + current->loadLibrary(); if(current->isClassAvailable(class_name)) return(current->createInstance(class_name)); } @@ -113,6 +115,8 @@ class MultiLibraryClassLoader for(unsigned int c = 0; c < active_loaders.size(); c++) { ClassLoader* current = active_loaders.at(c); + if (!current->isLibraryLoaded()) + current->loadLibrary(); if(current->isClassAvailable(class_name)) return(current->createUnmanagedInstance(class_name)); } diff --git a/src/multi_library_class_loader.cpp b/src/multi_library_class_loader.cpp index 8e4438ac..dece0921 100644 --- a/src/multi_library_class_loader.cpp +++ b/src/multi_library_class_loader.cpp @@ -39,7 +39,10 @@ enable_ondemand_loadunload_(enable_ondemand_loadunload) MultiLibraryClassLoader::~MultiLibraryClassLoader() { - shutdownAllClassLoaders(); + if (!isOnDemandLoadUnloadEnabled()) + shutdownAllClassLoaders(); // don't unload libs to avoid SEVERE WARNING + // TODO: free ClassLoaders in active_class_loaders_ + // However, we still need them in on-demand-load-unload mode. Otherwise we risk seg-faults. } std::vector MultiLibraryClassLoader::getRegisteredLibraries() From f32686f276c11c5b6d03daa97b436491ebfd6236 Mon Sep 17 00:00:00 2001 From: Robert Haschke Date: Sun, 3 Apr 2016 17:20:11 +0200 Subject: [PATCH 4/4] not unloading the ClassLoaders (to avoid the SEVERE WARNING) doesn't work either --- src/multi_library_class_loader.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/multi_library_class_loader.cpp b/src/multi_library_class_loader.cpp index dece0921..8e4438ac 100644 --- a/src/multi_library_class_loader.cpp +++ b/src/multi_library_class_loader.cpp @@ -39,10 +39,7 @@ enable_ondemand_loadunload_(enable_ondemand_loadunload) MultiLibraryClassLoader::~MultiLibraryClassLoader() { - if (!isOnDemandLoadUnloadEnabled()) - shutdownAllClassLoaders(); // don't unload libs to avoid SEVERE WARNING - // TODO: free ClassLoaders in active_class_loaders_ - // However, we still need them in on-demand-load-unload mode. Otherwise we risk seg-faults. + shutdownAllClassLoaders(); } std::vector MultiLibraryClassLoader::getRegisteredLibraries()