zone_writer.cc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Copyright (C) 2012 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 <datasrc/memory/zone_writer.h>
  15. #include <datasrc/memory/zone_data.h>
  16. #include <datasrc/memory/zone_table_segment.h>
  17. #include <memory>
  18. using std::auto_ptr;
  19. namespace isc {
  20. namespace datasrc {
  21. namespace memory {
  22. ZoneWriter::ZoneWriter(ZoneTableSegment& segment,
  23. const LoadAction& load_action,
  24. const dns::Name& origin,
  25. const dns::RRClass& rrclass) :
  26. segment_(segment),
  27. load_action_(load_action),
  28. origin_(origin),
  29. rrclass_(rrclass),
  30. zone_data_(NULL),
  31. state_(ZW_UNUSED)
  32. {
  33. if (!segment.isWritable()) {
  34. isc_throw(isc::InvalidOperation,
  35. "Attempt to construct ZoneWriter for a read-only segment");
  36. }
  37. }
  38. ZoneWriter::~ZoneWriter() {
  39. // Clean up everything there might be left if someone forgot, just
  40. // in case.
  41. cleanup();
  42. }
  43. void
  44. ZoneWriter::load() {
  45. if (state_ != ZW_UNUSED) {
  46. isc_throw(isc::InvalidOperation, "Trying to load twice");
  47. }
  48. zone_data_ = load_action_(segment_.getMemorySegment());
  49. if (!zone_data_) {
  50. // Bug inside load_action_.
  51. isc_throw(isc::InvalidOperation, "No data returned from load action");
  52. }
  53. state_ = ZW_LOADED;
  54. }
  55. void
  56. ZoneWriter::install() {
  57. if (state_ != ZW_LOADED) {
  58. isc_throw(isc::InvalidOperation, "No data to install");
  59. }
  60. // FIXME: This retry is currently untested, as there seems to be no
  61. // reasonable way to create a zone table segment with non-local memory
  62. // segment. Once there is, we should provide the test.
  63. while (state_ != ZW_INSTALLED) {
  64. try {
  65. ZoneTable* table(segment_.getHeader().getTable());
  66. if (table == NULL) {
  67. isc_throw(isc::Unexpected, "No zone table present");
  68. }
  69. const ZoneTable::AddResult result(table->addZone(
  70. segment_.getMemorySegment(),
  71. rrclass_, origin_,
  72. zone_data_));
  73. state_ = ZW_INSTALLED;
  74. zone_data_ = result.zone_data;
  75. } catch (const isc::util::MemorySegmentGrown&) {}
  76. }
  77. }
  78. void
  79. ZoneWriter::cleanup() {
  80. // We eat the data (if any) now.
  81. if (zone_data_ != NULL) {
  82. ZoneData::destroy(segment_.getMemorySegment(), zone_data_, rrclass_);
  83. zone_data_ = NULL;
  84. state_ = ZW_CLEANED;
  85. }
  86. }
  87. }
  88. }
  89. }