factory.cc 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright (C) 2011 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. #include "factory.h"
  15. #include "data_source.h"
  16. #include "database.h"
  17. #include "sqlite3_accessor.h"
  18. #include "memory_datasrc.h"
  19. #include <datasrc/logger.h>
  20. #include <dlfcn.h>
  21. using namespace isc::data;
  22. using namespace isc::datasrc;
  23. namespace isc {
  24. namespace datasrc {
  25. LibraryContainer::LibraryContainer(const std::string& name) {
  26. // use RTLD_GLOBAL so that shared symbols (e.g. exceptions)
  27. // are recognized as such
  28. ds_lib_ = dlopen(name.c_str(), RTLD_NOW | RTLD_GLOBAL);
  29. if (ds_lib_ == NULL) {
  30. isc_throw(DataSourceLibraryError, dlerror());
  31. }
  32. }
  33. LibraryContainer::~LibraryContainer() {
  34. dlclose(ds_lib_);
  35. }
  36. void*
  37. LibraryContainer::getSym(const char* name) {
  38. // Since dlsym can return NULL on success, we check for errors by
  39. // first clearing any existing errors with dlerror(), then calling dlsym,
  40. // and finally checking for errors with dlerror()
  41. dlerror();
  42. void *sym = dlsym(ds_lib_, name);
  43. const char* dlsym_error = dlerror();
  44. if (dlsym_error != NULL) {
  45. isc_throw(DataSourceLibrarySymbolError, dlsym_error);
  46. }
  47. return (sym);
  48. }
  49. DataSourceClientContainer::DataSourceClientContainer(const std::string& type,
  50. ConstElementPtr config)
  51. : ds_lib_(type + "_ds.so")
  52. {
  53. // We are casting from a data to a function pointer here
  54. // Some compilers (rightfully) complain about that, but
  55. // c-style casts are accepted the most here. If we run
  56. // into any that also don't like this, we might need to
  57. // use some form of union cast or memory copy to get
  58. // from the void* to the function pointer.
  59. ds_creator* ds_create = (ds_creator*)ds_lib_.getSym("createInstance");
  60. destructor_ = (ds_destructor*)ds_lib_.getSym("destroyInstance");
  61. std::string error;
  62. try {
  63. instance_ = ds_create(config, error);
  64. if (instance_ == NULL) {
  65. isc_throw(DataSourceError, error);
  66. }
  67. } catch (const std::exception& exc) {
  68. isc_throw(DataSourceError, "Unknown uncaught exception from " + type +
  69. " createInstance: " + exc.what());
  70. } catch (...) {
  71. isc_throw(DataSourceError, "Unknown uncaught exception from " + type);
  72. }
  73. }
  74. DataSourceClientContainer::~DataSourceClientContainer() {
  75. destructor_(instance_);
  76. }
  77. } // end namespace datasrc
  78. } // end namespace isc