library_manager_collection.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #ifndef LIBRARY_MANAGER_COLLECTION_H
  15. #define LIBRARY_MANAGER_COLLECTION_H
  16. #include <exceptions/exceptions.h>
  17. #include <boost/shared_ptr.hpp>
  18. #include <vector>
  19. namespace isc {
  20. namespace hooks {
  21. /// @brief LoadLibraries not called
  22. ///
  23. /// Thrown if an attempt is made get a CalloutManager before the libraries
  24. /// have been loaded.
  25. class LoadLibrariesNotCalled : public Exception {
  26. public:
  27. LoadLibrariesNotCalled(const char* file, size_t line, const char* what) :
  28. isc::Exception(file, line, what) {}
  29. };
  30. // Forward declarations
  31. class CalloutManager;
  32. class LibraryManager;
  33. /// @brief Library manager collection
  34. ///
  35. /// The LibraryManagerCollection class, as the name implies, is responsible for
  36. /// managing the collection of LibraryManager objects that describe the loaded
  37. /// libraries. As such, it converts a single operation (e.g load libraries)
  38. /// into multiple operations, one per library. However, the class does more
  39. /// than that - it provides a single object with which to manage lifetimes.
  40. ///
  41. /// As described in the LibraryManager documentation, a CalloutHandle may end
  42. /// up with pointers to memory within the address space of a loaded library.
  43. /// If the library is unloaded before this address space is deleted, the
  44. /// deletion of the CalloutHandle may attempt to free memory into the newly-
  45. /// unmapped address space and cause a segmentation fault.
  46. ///
  47. /// To prevent this, each CalloutHandle maintains a shared pointer to the
  48. /// LibraryManagerCollection current when it was created. In addition, the
  49. /// containing HooksManager object also maintains a shared pointer to it. A
  50. /// a LibraryManagerCollection is never explicitly deleted: when a new set
  51. /// of libraries is loaded, the HooksManager clears its pointer to the
  52. /// collection. The LibraryManagerCollection is only destroyed when all
  53. /// CallHandle objects referencing it are destroyed.
  54. ///
  55. /// Note that this does not completely solve the problem - a hook function may
  56. /// have modified a packet being processed by the server and that packet may
  57. /// hold a pointer to memory in the library's virtual address space. To avoid
  58. /// a segmentation fault, that packet needs to free the memory before the
  59. /// LibraryManagerCollection is destroyed and this places demands on the server
  60. /// code. However, the link with the CalloutHandle does at least mean that
  61. /// authors of server code do not need to be so careful about when they destroy
  62. /// CalloutHandles.
  63. ///
  64. /// The collection object also provides a utility function to validate a set
  65. /// of libraries. The function checks that each library exists, can be opened,
  66. /// that the "version" function exists and return the right number.
  67. class LibraryManagerCollection {
  68. public:
  69. /// @brief Constructor
  70. ///
  71. /// @param libraries List of libraries that this collection will manage.
  72. /// The order of the libraries is important.
  73. LibraryManagerCollection(const std::vector<std::string>& libraries)
  74. : library_names_(libraries)
  75. {}
  76. /// @brief Destructor
  77. ///
  78. /// Unloads all loaded libraries.
  79. ~LibraryManagerCollection() {
  80. static_cast<void>(unloadLibraries());
  81. }
  82. /// @brief Load libraries
  83. ///
  84. /// Loads the libraries. This creates the LibraryManager associated with
  85. /// each library and calls its loadLibrary() method. If a library fails
  86. /// to load, the loading is abandoned and all libraries loaded so far
  87. /// are unloaded.
  88. ///
  89. /// @return true if all libraries loaded, false if one or more failed t
  90. //// load.
  91. bool loadLibraries();
  92. /// @brief Get callout manager
  93. ///
  94. /// Returns a callout manager that can be used with this set of loaded
  95. /// libraries (even if the number of loaded libraries is zero). This
  96. /// method may only be caslled after loadLibraries() has been called.
  97. ///
  98. /// @return Pointer to a callout manager for this set of libraries.
  99. ///
  100. /// @throw LoadLibrariesNotCalled Thrown if this method is called between
  101. /// construction and the time loadLibraries() is called.
  102. boost::shared_ptr<CalloutManager> getCalloutManager() const;
  103. /// @brief Get library names
  104. ///
  105. /// Returns the list of library names. If called before loadLibraries(),
  106. /// the list is the list of names to be loaded; if called afterwards, it
  107. /// is the list of libraries that have been loaded.
  108. std::vector<std::string> getLibraryNames() const {
  109. return (library_names_);
  110. }
  111. /// @brief Get number of loaded libraries
  112. ///
  113. /// Mainly for testing, this returns the number of libraries that are
  114. /// loaded.
  115. ///
  116. /// @return Number of libraries that are loaded.
  117. int getLoadedLibraryCount() const;
  118. /// @brief Validate libraries
  119. ///
  120. /// Utility function to validate libraries. It checks that the libraries
  121. /// exist, can be opened, that a "version" function is present in them, and
  122. /// that it returns the right number. All errors are logged.
  123. ///
  124. /// @param libraries List of libraries to validate
  125. ///
  126. /// @return Vector of libraries that faled to validate, or an empty vector
  127. /// if all validated.
  128. static std::vector<std::string>
  129. validateLibraries(const std::vector<std::string>& libraries);
  130. protected:
  131. /// @brief Unload libraries
  132. ///
  133. /// Unloads and closes all loaded libraries. They are unloaded in the
  134. /// reverse order to the order in which they were loaded.
  135. void unloadLibraries();
  136. private:
  137. /// Vector of library names
  138. std::vector<std::string> library_names_;
  139. /// Vector of library managers
  140. std::vector<boost::shared_ptr<LibraryManager> > lib_managers_;
  141. /// Callout manager to be associated with the libraries
  142. boost::shared_ptr<CalloutManager> callout_manager_;
  143. };
  144. } // namespace hooks
  145. } // namespace isc
  146. #endif // LIBRARY_MANAGER_COLLECTION_H