BIND 10 trac2980, updated. 2bde65105b86a512aa798cac5bcad723bafb38c9 [2980] Added missing LibraryManagerCollection files to the repository

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Jun 24 19:43:00 UTC 2013


The branch, trac2980 has been updated
       via  2bde65105b86a512aa798cac5bcad723bafb38c9 (commit)
      from  418f35f58458de0480d6a58299f06721481d9196 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 2bde65105b86a512aa798cac5bcad723bafb38c9
Author: Stephen Morris <stephen at isc.org>
Date:   Mon Jun 24 20:42:27 2013 +0100

    [2980] Added missing LibraryManagerCollection files to the repository

-----------------------------------------------------------------------

Summary of changes:
 src/lib/hooks/library_manager_collection.cc |  114 +++++++++++++++++++++++
 src/lib/hooks/library_manager_collection.h  |  133 +++++++++++++++++++++++++++
 2 files changed, 247 insertions(+)
 create mode 100644 src/lib/hooks/library_manager_collection.cc
 create mode 100644 src/lib/hooks/library_manager_collection.h

-----------------------------------------------------------------------
diff --git a/src/lib/hooks/library_manager_collection.cc b/src/lib/hooks/library_manager_collection.cc
new file mode 100644
index 0000000..d3f7f34
--- /dev/null
+++ b/src/lib/hooks/library_manager_collection.cc
@@ -0,0 +1,114 @@
+// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <hooks/callout_manager.h>
+#include <hooks/library_manager.h>
+#include <hooks/library_manager_collection.h>
+
+namespace isc {
+namespace hooks {
+
+// Return callout manager for the loaded libraries.  This call is only valid
+// after one has been created for the loaded libraries (which includes the
+// case of no loaded libraries).
+//
+// Note that there is no real connection between the callout manager and the
+// libraries, other than it knows the number of libraries so can do sanity
+// checks on values passed to it.  However, this may change in the future,
+// so the hooks framework is written such that a callout manager is used only
+// with the LibraryManagerCollection that created it.  It is also the reason
+// why each LibraryManager contains a pointer to this CalloutManager.
+
+boost::shared_ptr<CalloutManager>
+LibraryManagerCollection::getCalloutManager() const {
+
+    // Only return a pointer if we have a CalloutManager created.
+    if (! callout_manager_) {
+        isc_throw(LoadLibrariesNotCalled, "must load hooks libraries before "
+                  "attempting to retrieve a CalloutManager for them");
+    }
+
+    return (callout_manager_);
+}
+
+// Load a set of libraries
+
+bool
+LibraryManagerCollection::loadLibraries() {
+
+    // Unload libraries if any are loaded.
+    static_cast<void>(unloadLibraries());
+
+    // Create the callout manager.  A pointer to this is maintained by
+    // each library.  Note that the callout manager does not hold any memory
+    // allocated by a library: although a library registers a callout (and so
+    // causes the creation of an entry in the CalloutManager's callout list),
+    // that creation is done by the CalloutManager itself.  The CalloutManager
+    // is created within the server.
+    //
+    // The upshot of this is that it is therefore safe for the CalloutManager
+    // to be deleted after all associated libraries are deleted, hence this
+    // link (LibraryManager -> CalloutManager) is safe.
+    callout_manager_.reset(new CalloutManager(library_names_.size()));
+
+    // Now iterate through the libraries are load them one by one.  We'll
+    for (int i = 0; i < library_names_.size(); ++i) {
+        // Create a pointer to the new library manager.  The index of this
+        // library is determined by the number of library managers currently
+        // loaded: note that the library indexes run from 1 to (number of loaded
+        // libraries).
+        boost::shared_ptr<LibraryManager> manager(
+                new LibraryManager(library_names_[i], lib_managers_.size() + 1,
+                                   callout_manager_));
+
+        // Load the library.  On success, add it to the list of loaded
+        // libraries.  On failure, an error will have been logged and the
+        // library closed.
+        if (manager->loadLibrary()) {
+            lib_managers_.push_back(manager);
+        }
+    }
+
+    // Update the CalloutManager's idea of the number of libraries it is
+    // handling.
+    callout_manager_->setNumLibraries(lib_managers_.size());
+
+    // Get an indication of whether all libraries loaded successfully.
+    bool status = (library_names_.size() == lib_managers_.size());
+
+    // Don't need the library names any more, so free up the space.
+    library_names_.clear();
+
+    return (status);
+}
+
+// Unload the libraries.
+
+void
+LibraryManagerCollection::unloadLibraries() {
+
+    // Delete the library managers in the reverse order to which they were
+    // created, then clear the library manager vector.
+    for (int i = lib_managers_.size() - 1; i >= 0; --i) {
+        lib_managers_[i].reset();
+    }
+    lib_managers_.clear();
+
+    // Get rid of the callout manager. (The other member, the list of library
+    // names, was cleared when the libraries were loaded.)
+    callout_manager_.reset();
+}
+
+} // namespace hooks
+} // namespace isc
diff --git a/src/lib/hooks/library_manager_collection.h b/src/lib/hooks/library_manager_collection.h
new file mode 100644
index 0000000..c0f6def
--- /dev/null
+++ b/src/lib/hooks/library_manager_collection.h
@@ -0,0 +1,133 @@
+// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef LIBRARY_MANAGER_COLLECTION_H
+#define LIBRARY_MANAGER_COLLECTION_H
+
+#include <exceptions/exceptions.h>
+
+#include <boost/shared_ptr.hpp>
+
+#include <vector>
+
+namespace isc {
+namespace hooks {
+
+/// @brief LoadLibraries not called
+///
+/// Thrown if an attempt is made get a CalloutManager before the libraries
+/// have been loaded.
+class LoadLibrariesNotCalled : public Exception {
+public:
+    LoadLibrariesNotCalled(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
+
+// Forward declarations
+class CalloutManager;
+class LibraryManager;
+
+/// @brief Library manager collection
+///
+/// The LibraryManagerCollection class, as the name implies, is responsible for
+/// managing the collection of LibraryManager objects that describe the loaded
+/// libraries.  As such, it converts a single operation (e.g load libraries)
+/// into multiple operations, one per library.  However, the class does more
+/// than that - it provides a single object with which to manage lifetimes.
+///
+/// As described in the LibraryManager documentation, a CalloutHandle may end
+/// up with pointers to memory within the address space of a loaded library.
+/// If the library is unloaded before this address space is deleted, the
+/// deletion of the CalloutHandle may attempt to free memory into the newly-
+/// unmapped address space and cause a segmentation fault.
+///
+/// To prevent this, each CalloutHandle maintains a shared pointer to the
+/// LibraryManagerCollection current when it was created.  In addition, the
+/// containing HooksManager object also maintains a shared pointer to it.  A
+/// a LibraryManagerCollection is never explicitly deleted: when a new set
+/// of libraries is loaded, the HooksManager clears its pointer to the
+/// collection.  The LibraryManagerCollection is only destroyed when all
+/// CallHandle objects referencing it are destroyed.
+///
+/// Note that this does not completely solve the problem - a hook function may
+/// have modified a packet being processed by the server and that packet may
+/// hold a pointer to memory in the library's virtual address space. To avoid
+/// a segmentation fault, that packet needs to free the memory before the
+/// LibraryManagerCollection is destroyed and this places demands on the server
+/// code.  However, the link with the CalloutHandle does at least mean that
+/// authors of server code do not need to be so careful about when they destroy
+/// CalloutHandles.
+
+class LibraryManagerCollection {
+public:
+    /// @brief Constructor
+    ///
+    /// @param List of libraries that this collection will manage.  The order
+    ///        of the libraries is important.
+    LibraryManagerCollection(const std::vector<std::string>& libraries)
+        : library_names_(libraries)
+    {}
+
+    /// @brief Destructor
+    ///
+    /// Unloads all loaded libraries.
+    ~LibraryManagerCollection() {
+        static_cast<void>(unloadLibraries());
+    }
+
+    /// @brief Load libraries
+    ///
+    /// Loads the libraries.  This creates the LibraryManager associated with
+    /// each library and calls its loadLibrary() method.  If a library fails
+    /// to load, the fact is noted but attempts are made to load the remaining
+    /// libraries.
+    bool loadLibraries();
+
+    /// @brief Get callout manager
+    ///
+    /// Returns a callout manager that can be used with this set of loaded
+    /// libraries (even if the number of loaded libraries is zero).  This
+    /// method may only be caslled after loadLibraries() has been called.
+    ///
+    /// @return Pointer to a callout manager for this set of libraries.
+    ///
+    /// @throw LoadLibrariesNotCalled Thrown if this method is called between
+    ///        construction and the time loadLibraries() is called.
+    boost::shared_ptr<CalloutManager> getCalloutManager() const;
+
+protected:
+    /// @brief Unload libraries
+    ///
+    /// Unloads and closes all loaded libraries.  They are unloaded in the
+    /// reverse order to the order in which they were loaded.
+    void unloadLibraries();
+
+private:
+
+    /// Vector of library names
+    std::vector<std::string>                        library_names_;
+
+    /// Vector of library managers
+    std::vector<boost::shared_ptr<LibraryManager> > lib_managers_;
+
+    /// Callout manager to be associated with the libraries
+    boost::shared_ptr<CalloutManager>               callout_manager_;
+};
+
+} // namespace hooks
+} // namespace isc
+
+
+#endif // LIBRARY_MANAGER_COLLECTION_H



More information about the bind10-changes mailing list