// 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_HANDLE_H #define LIBRARY_HANDLE_H #include namespace isc { namespace hooks { // Forward declarations class CalloutHandle; class CalloutManager; /// Typedef for a callout pointer. (Callouts must have "C" linkage.) extern "C" { typedef int (*CalloutPtr)(CalloutHandle&); }; /// @brief Library handle /// /// This class is accessed by the user library when registering callouts, /// either by the library's load() function, or by one of the callouts /// themselves. /// /// It is really little more than a shell around the CalloutManager. By /// presenting this object to the user-library callouts, callouts can manage /// the callout list for their own library, but cannot affect the callouts /// registered by other libraries. /// /// (This restriction is achieved by the CalloutManager maintaining the concept /// of the "current library". When a callout is registered - either by the /// library's load() function, or by a callout in the library - the registration /// information includes the library active at the time. When that callout is /// called, the CalloutManager uses that information to set the "current /// library": the registration functions only operator on data whose /// associated library is equal to the "current library".) class LibraryHandle { public: /// @brief Constructor /// /// @param manager Back pointer to the containing CalloutManager. /// This pointer is used to access appropriate methods in that /// object. Note that the "raw" pointer is safe - the only /// instance of the LibraryHandle in the system is as a member of /// the CalloutManager to which it points. /// /// @param index Index of the library to which the LibraryHandle applies. /// If negative, the library index as set in the CalloutManager is /// used. Otherwise the current library index is saved, this value /// is set as the current index, the registration call is made, and /// the CalloutManager's library index is reset. Note: although -1 /// is a valid argument value for /// isc::hooks::CalloutManager::setLibraryIndex(), in this class is /// is used as a sentinel to indicate that the library index in /// isc::util::CalloutManager should not be set or reset. LibraryHandle(CalloutManager* manager, int index = -1) : callout_manager_(manager), index_(index) {} /// @brief Register a callout on a hook /// /// Registers a callout function with a given hook. The callout is added /// to the end of the callouts for the current library that are associated /// with that hook. /// /// @param name Name of the hook to which the callout is added. /// @param callout Pointer to the callout function to be registered. /// /// @throw NoSuchHook The hook name is unrecognised. /// @throw Unexpected The hook name is valid but an internal data structure /// is of the wrong size. void registerCallout(const std::string& name, CalloutPtr callout); /// @brief De-Register a callout on a hook /// /// Searches through the functions registered by the current library with /// the named hook and removes all entries matching the callout. It does /// not affect callouts registered by other libraries. /// /// @param name Name of the hook from which the callout is removed. /// @param callout Pointer to the callout function to be removed. /// /// @return true if a one or more callouts were deregistered. /// /// @throw NoSuchHook The hook name is unrecognised. /// @throw Unexpected The hook name is valid but an internal data structure /// is of the wrong size. bool deregisterCallout(const std::string& name, CalloutPtr callout); /// @brief Removes all callouts on a hook /// /// Removes all callouts associated with a given hook that were registered. /// by the current library. It does not affect callouts that were /// registered by other libraries. /// /// @param name Name of the hook from which the callouts are removed. /// /// @return true if one or more callouts were deregistered. /// /// @throw NoSuchHook Thrown if the hook name is unrecognised. bool deregisterAllCallouts(const std::string& name); private: /// @brief Copy constructor /// /// Private (with no implementation) as it makes no sense to copy an object /// of this type. All code receives a reference to an existing handle which /// is tied to a particular CalloutManager. Creating a copy of that handle /// runs the risk of a "dangling pointer" to the original handle's callout /// manager. /// /// @param Unused - should be the object to copy. LibraryHandle(const LibraryHandle&); /// @brief Assignment operator /// /// Declared private like the copy constructor for the same reasons. It too /// has no implementation. /// /// @param Unused - should be the object to copy. LibraryHandle& operator=(const LibraryHandle&); /// Back pointer to the collection object for the library CalloutManager* callout_manager_; /// Library index to which this handle applies. -1 indicates that it /// applies to whatever index is current in the CalloutManager. int index_; }; } // namespace util } // namespace isc #endif // LIBRARY_HANDLE_H