Browse Source

[2980] Added HooksManager load/unload libraries methods

Stephen Morris 12 years ago
parent
commit
b4bf719aa5

+ 47 - 9
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<string> 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<string> 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<std::string>& 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<std::string>& 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();
+}
 
 
 

+ 35 - 11
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<std::string>& /* libraries */) {return false;}
+    static bool loadLibraries(const std::vector<std::string>& 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<std::string>& 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
 

+ 23 - 30
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<CalloutManager> 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<std::string> 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<CalloutManager> 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.