From: Stephen Morris Date: Mon, 24 Jun 2013 11:02:07 +0000 (+0100) Subject: [2980] Added HooksManager load/unload libraries methods X-Git-Tag: bind10-1.2.0beta1-release~345^2~16 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b4bf719aa55ad684dbfa5faa39aa93ebf89bac18;p=thirdparty%2Fkea.git [2980] Added HooksManager load/unload libraries methods --- diff --git a/src/lib/hooks/hooks_manager.cc b/src/lib/hooks/hooks_manager.cc index 0b304d6ee9..de1a2a03b4 100644 --- a/src/lib/hooks/hooks_manager.cc +++ b/src/lib/hooks/hooks_manager.cc @@ -49,17 +49,15 @@ HooksManager::getHooksManager() { // Perform conditional initialization if nothing is loaded. void -HooksManager::conditionallyInitialize() { - if (!lm_collection_) { +HooksManager::performConditionalInitialization() { - // Nothing present, so create the collection with any empty set of - // libraries, and get the CalloutManager. - vector libraries; - lm_collection_.reset(new LibraryManagerCollection(libraries)); - lm_collection_->loadLibraries(); + // Nothing present, so create the collection with any empty set of + // libraries, and get the CalloutManager. + vector libraries; + lm_collection_.reset(new LibraryManagerCollection(libraries)); + lm_collection_->loadLibraries(); - callout_manager_ = lm_collection_->getCalloutManager(); - } + callout_manager_ = lm_collection_->getCalloutManager(); } // Create a callout handle @@ -102,6 +100,46 @@ HooksManager::callCallouts(int index, CalloutHandle& handle) { return (getHooksManager().callCalloutsInternal(index, handle)); } +// Load the libraries. This will delete the previously-loaded libraries +// (if present) and load new ones. + +bool +HooksManager::loadLibrariesInternal(const std::vector& libraries) { + // Unload current set of libraries (if any are loaded). + unloadLibrariesInternal(); + + // Create the library manager and load the libraries. + lm_collection_.reset(new LibraryManagerCollection(libraries)); + bool status = lm_collection_->loadLibraries(); + + // ... and obtain the callout manager for them. + callout_manager_ = lm_collection_->getCalloutManager(); + + return (status); +} + +bool +HooksManager::loadLibraries(const std::vector& libraries) { + return (getHooksManager().loadLibrariesInternal(libraries)); +} + +// Unload the libraries. This just deletes all internal objects which will +// cause the libraries to be unloaded. + +void +HooksManager::unloadLibrariesInternal() { + // The order of deletion does not matter here, as each library manager + // holds its own pointer to the callout manager. However, we may as + // well delete the library managers first: if there are no other references + // to the callout manager, the second statement will delete it, which may + // ease debugging. + lm_collection_.reset(); + callout_manager_.reset(); +} + +void HooksManager::unloadLibraries() { + getHooksManager().unloadLibrariesInternal(); +} diff --git a/src/lib/hooks/hooks_manager.h b/src/lib/hooks/hooks_manager.h index 20483098e8..222d97388e 100644 --- a/src/lib/hooks/hooks_manager.h +++ b/src/lib/hooks/hooks_manager.h @@ -47,12 +47,6 @@ public: /// @return Reference to the singleton hooks manager. static HooksManager& getHooksManager(); - /// @brief Reset hooks manager - /// - /// Resets the hooks manager to the initial state. This should only be - /// called by test functions, so causes a warning message to be output. - void reset() {} - /// @brief Load and reload libraries /// /// Loads the list of libraries into the server address space. For each @@ -73,7 +67,7 @@ public: /// @return true if all libraries loaded without a problem, false if one or /// more libraries failed to load. In the latter case, message will /// be logged that give the reason. - bool loadLibraries(const std::vector& /* libraries */) {return false;} + static bool loadLibraries(const std::vector& libraries); /// @brief Unload libraries /// @@ -88,7 +82,7 @@ public: /// /// @return true if all libraries unloaded successfully, false on an error. /// In the latter case, an error message will have been output. - bool unloadLibraries() {return false;} + static void unloadLibraries(); /// @brief Are callouts present? /// @@ -168,8 +162,23 @@ private: HooksManager(); //@{ - /// The following correspond to the each of the static methods above - /// but operate on the current instance. + /// The following methods correspond to similarly-named static methods, + /// but actually do the work on the singleton instance of the HooksManager. + /// See the descriptions of the static methods for more details. + + /// @brief Load and reload libraries + /// + /// @param libraries List of libraries to be loaded. The order is + /// important, as it determines the order that callouts on the same + /// hook will be called. + /// + /// @return true if all libraries loaded without a problem, false if one or + /// more libraries failed to load. In the latter case, message will + /// be logged that give the reason. + bool loadLibrariesInternal(const std::vector& libraries); + + /// @brief Unload libraries + void unloadLibrariesInternal(); /// @brief Are callouts present? /// @@ -196,6 +205,13 @@ private: //@} + /// @brief Initialization to No Libraries + /// + /// Initializes the hooks manager with an "empty set" of libraries. This + /// method is called if conditionallyInitialize() determines that such + /// initialization is needed. + void performConditionalInitialization(); + /// @brief Conditional initialization of the hooks manager /// /// loadLibraries() performs the initialization of the HooksManager, @@ -204,7 +220,15 @@ private: /// whenever any hooks execution function is invoked (checking callouts, /// calling callouts or returning a callout handle). If the HooksManager /// is unitialised, it will initialize it with an "empty set" of libraries. - void conditionallyInitialize(); + /// + /// For speed, the test of whether initialization is required is done + /// in-line here. The actual initialization is performed in + /// performConditionalInitialization(). + void conditionallyInitialize() { + if (!lm_collection_) { + performConditionalInitialization(); + } + } // Members diff --git a/src/lib/hooks/tests/hooks_manager_unittest.cc b/src/lib/hooks/tests/hooks_manager_unittest.cc index 0d827ae46b..ec2374c37e 100644 --- a/src/lib/hooks/tests/hooks_manager_unittest.cc +++ b/src/lib/hooks/tests/hooks_manager_unittest.cc @@ -41,9 +41,17 @@ public: /// Reset the hooks manager. The hooks manager is a singleton, so needs /// to be reset for each test. HooksManagerTest() { - HooksManager::getHooksManager().reset(); + HooksManager::unloadLibraries(); } + /// @brief Destructor + /// + /// Unload all libraries. + ~HooksManagerTest() { + HooksManager::unloadLibraries(); + } + + /// @brief Call callouts test /// /// See the header for HooksCommonTestClass::execute for details. @@ -91,9 +99,9 @@ public: } }; -/* + // This is effectively the same test as for LibraryManager, but using the -// LibraryManagerCollection object. +// HooksManager object. TEST_F(HooksManagerTest, LoadLibraries) { @@ -102,14 +110,8 @@ TEST_F(HooksManagerTest, LoadLibraries) { library_names.push_back(std::string(FULL_CALLOUT_LIBRARY)); library_names.push_back(std::string(BASIC_CALLOUT_LIBRARY)); - // Set up the library manager collection and get the callout manager we'll - // be using. - PublicLibraryManagerCollection lm_collection(library_names); - // Load the libraries. - EXPECT_TRUE(lm_collection.loadLibraries()); - boost::shared_ptr manager = - lm_collection.getCalloutManager(); + EXPECT_TRUE(HooksManager::loadLibraries(library_names)); // Execute the callouts. The first library implements the calculation. // @@ -125,17 +127,17 @@ TEST_F(HooksManagerTest, LoadLibraries) { // r3 = ((10 * d1 + d1) - d2) * d2 * d3 - d3 { SCOPED_TRACE("Doing calculation with libraries loaded"); - executeCallCallouts(manager, 10, 3, 33, 2, 62, 3, 183); + executeCallCallouts(10, 3, 33, 2, 62, 3, 183); } // Try unloading the libraries. - EXPECT_NO_THROW(lm_collection.unloadLibraries()); + EXPECT_NO_THROW(HooksManager::unloadLibraries()); // Re-execute the calculation - callouts can be called but as nothing // happens, the result should always be -1. { SCOPED_TRACE("Doing calculation with libraries not loaded"); - executeCallCallouts(manager, -1, 3, -1, 22, -1, 83, -1); + executeCallCallouts(-1, 3, -1, 22, -1, 83, -1); } } @@ -143,7 +145,7 @@ TEST_F(HooksManagerTest, LoadLibraries) { // an error when loaded. It is expected that the failing library will not be // loaded, but others will be. -TEST_F(LibraryManagerCollectionTest, LoadLibrariesWithError) { +TEST_F(HooksManagerTest, LoadLibrariesWithError) { // Set up the list of libraries to be loaded. std::vector library_names; @@ -151,18 +153,9 @@ TEST_F(LibraryManagerCollectionTest, LoadLibrariesWithError) { library_names.push_back(std::string(INCORRECT_VERSION_LIBRARY)); library_names.push_back(std::string(BASIC_CALLOUT_LIBRARY)); - // Set up the library manager collection and get the callout manager we'll - // be using. - PublicLibraryManagerCollection lm_collection(library_names); - - // Load the libraries. We expect a failure status to be returned as - // one of the libraries failed to load. - EXPECT_FALSE(lm_collection.loadLibraries()); - boost::shared_ptr manager = - lm_collection.getCalloutManager(); - - // Expect only two libraries were loaded. - EXPECT_EQ(2, manager->getNumLibraries()); + // Load the libraries. We expect a failure return because one of the + // libraries fails to load. + EXPECT_FALSE(HooksManager::loadLibraries(library_names)); // Execute the callouts. The first library implements the calculation. // @@ -178,20 +171,20 @@ TEST_F(LibraryManagerCollectionTest, LoadLibrariesWithError) { // r3 = ((10 * d1 + d1) - d2) * d2 * d3 - d3 { SCOPED_TRACE("Doing calculation with libraries loaded"); - executeCallCallouts(manager, 10, 3, 33, 2, 62, 3, 183); + executeCallCallouts(10, 3, 33, 2, 62, 3, 183); } // Try unloading the libraries. - EXPECT_NO_THROW(lm_collection.unloadLibraries()); + EXPECT_NO_THROW(HooksManager::unloadLibraries()); // Re-execute the calculation - callouts can be called but as nothing // happens, the result should always be -1. { SCOPED_TRACE("Doing calculation with libraries not loaded"); - executeCallCallouts(manager, -1, 3, -1, 22, -1, 83, -1); + executeCallCallouts(-1, 3, -1, 22, -1, 83, -1); } } -*/ + // Check that everything works even with no libraries loaded. First that // calloutsPresent() always returns false.