123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- // 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.
- ///
- /// The collection object also provides a utility function to validate a set
- /// of libraries. The function checks that each library exists, can be opened,
- /// that the "version" function exists and return the right number.
- class LibraryManagerCollection {
- public:
- /// @brief Constructor
- ///
- /// @param libraries 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 loading is abandoned and all libraries loaded so far
- /// are unloaded.
- ///
- /// @return true if all libraries loaded, false if one or more failed t
- //// load.
- 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;
- /// @brief Get library names
- ///
- /// Returns the list of library names. If called before loadLibraries(),
- /// the list is the list of names to be loaded; if called afterwards, it
- /// is the list of libraries that have been loaded.
- std::vector<std::string> getLibraryNames() const {
- return (library_names_);
- }
- /// @brief Get number of loaded libraries
- ///
- /// Mainly for testing, this returns the number of libraries that are
- /// loaded.
- ///
- /// @return Number of libraries that are loaded.
- int getLoadedLibraryCount() const;
- /// @brief Validate libraries
- ///
- /// Utility function to validate libraries. It checks that the libraries
- /// exist, can be opened, that a "version" function is present in them, and
- /// that it returns the right number. All errors are logged.
- ///
- /// @param libraries List of libraries to validate
- ///
- /// @return Vector of libraries that faled to validate, or an empty vector
- /// if all validated.
- static std::vector<std::string>
- validateLibraries(const std::vector<std::string>& libraries);
- 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
|