Browse Source

[1206] update documentation, and change DLHolder name

Jelte Jansen 13 years ago
parent
commit
58b8435541
3 changed files with 59 additions and 9 deletions
  1. 44 0
      src/lib/datasrc/client.h
  2. 3 3
      src/lib/datasrc/factory.cc
  3. 12 6
      src/lib/datasrc/factory.h

+ 44 - 0
src/lib/datasrc/client.h

@@ -22,6 +22,47 @@
 
 #include <datasrc/zone.h>
 
+/// \file
+/// Datasource clients
+///
+/// The data source client API is specified in client.h, and provides the
+/// functionality to query and modify data in the data sources. There are
+/// multiple datasource implementations, and by subclassing DataSourceClient or
+/// DatabaseClient, more can be added.
+///
+/// All datasources are implemented as loadable modules, with a name of the
+/// form "<type>_ds.so". This has been chosen intentionally, to minimize
+/// confusion and potential mistakes.
+///
+/// In order to use a datasource client backend, the class
+/// DataSourceClientContainer is provided in factory.h; this will load the
+/// library, set up the instance, and clean everything up once it is destroyed.
+///
+/// Access to the actual instance is provided with the getInstance() method
+/// in DataSourceClientContainer
+///
+/// \note Depending on actual usage, we might consider making the container
+/// a transparent abstraction layer, so it can be used as a DataSourceClient
+/// directly. This has some other implications though so for now the only access
+/// provided is through getInstance()).
+///
+/// For datasource backends, we use a dynamically loaded library system (with
+/// dlopen()). This library must contain the following things;
+/// - A subclass of DataSourceClient or DatabaseClient (which itself is a
+///   subclass of DataSourceClient)
+/// - A creator function for an instance of that subclass, of the form:
+/// \code
+/// extern "C" DataSourceClient* createInstance(isc::data::ConstElementPtr cfg);
+/// \endcode
+/// - A destructor for said instance, of the form:
+/// \code
+/// extern "C" void destroyInstance(isc::data::DataSourceClient* instance);
+/// \endcode
+///
+/// See the documentation for the \link DataSourceClient \endlink class for
+/// more information on implementing subclasses of it.
+///
+
 namespace isc {
 namespace datasrc {
 
@@ -39,6 +80,9 @@ typedef boost::shared_ptr<ZoneIterator> ZoneIteratorPtr;
 /// operations to other classes; in general methods of this class act as
 /// factories of these other classes.
 ///
+/// See \link datasrc/client.h datasrc/client.h \endlink for more information
+/// on adding datasource implementations.
+///
 /// The following derived classes are currently (expected to be) provided:
 /// - \c InMemoryClient: A client of a conceptual data source that stores
 /// all necessary data in memory for faster lookups

+ 3 - 3
src/lib/datasrc/factory.cc

@@ -27,19 +27,19 @@ using namespace isc::datasrc;
 namespace isc {
 namespace datasrc {
 
-DLHolder::DLHolder(const std::string& name) {
+LibraryContainer::LibraryContainer(const std::string& name) {
     ds_lib_ = dlopen(name.c_str(), RTLD_NOW | RTLD_LOCAL);
     if (ds_lib_ == NULL) {
         isc_throw(DataSourceLibraryError, dlerror());
     }
 }
 
-DLHolder::~DLHolder() {
+LibraryContainer::~LibraryContainer() {
     dlclose(ds_lib_);
 }
 
 void*
-DLHolder::getSym(const char* name) {
+LibraryContainer::getSym(const char* name) {
     // Since dlsym can return NULL on success, we check for errors by
     // first clearing any existing errors with dlerror(), then calling dlsym,
     // and finally checking for errors with dlerror()

+ 12 - 6
src/lib/datasrc/factory.h

@@ -63,7 +63,7 @@ typedef void ds_destructor(DataSourceClient* instance);
 ///       in other places than for dynamically loading datasources, then, apart
 ///       from moving it to another location, we also need to make the
 ///       exceptions raised more general.
-class DLHolder {
+class LibraryContainer {
 public:
     /// \brief Constructor
     ///
@@ -72,12 +72,12 @@ public:
     ///
     /// \exception DataSourceLibraryError If the library cannot be found or
     ///            cannot be loaded.
-    DLHolder(const std::string& name);
+    LibraryContainer(const std::string& name);
 
     /// \brief Destructor
     ///
     /// Cleans up the library by calling dlclose()
-    ~DLHolder();
+    ~LibraryContainer();
 
     /// \brief Retrieve a symbol
     ///
@@ -101,7 +101,9 @@ private:
 /// Given a datasource type and a type-specific set of configuration data,
 /// the corresponding dynamic library is loaded (if it hadn't been already),
 /// and an instance is created. This instance is stored within this structure,
-/// and can be accessed through getInstance().
+/// and can be accessed through getInstance(). Upon destruction of this
+/// container, the stored instance of the DataSourceClient is deleted with
+/// the destructor function provided by the loaded library.
 ///
 /// The 'type' is actually the name of the library, minus the '_ds.so' postfix
 /// Datasource implementation libraries therefore have a fixed name, both for
@@ -112,8 +114,12 @@ private:
 /// There are of course some demands to an implementation, not all of which
 /// can be verified compile-time. It must provide a creator and destructor
 /// functions. The creator function must return an instance of a subclass of
-/// DataSourceClient.
+/// DataSourceClient. The prototypes of these functions are as follows:
+/// \code
+/// extern "C" DataSourceClient* createInstance(isc::data::ConstElementPtr cfg);
 ///
+/// extern "C" void destroyInstance(isc::data::DataSourceClient* instance);
+/// \endcode
 class DataSourceClientContainer {
 public:
     /// \brief Constructor
@@ -145,7 +151,7 @@ public:
 private:
     DataSourceClient* instance_;
     ds_destructor* destructor_;
-    DLHolder ds_lib_;
+    LibraryContainer ds_lib_;
 };
 
 } // end namespace datasrc