if (loaded_) {
isc_throw(isc::Unexpected, "Trying to load twice");
}
- loaded_ = true;
zone_data_ = load_action_(segment_->getMemorySegment());
isc_throw(isc::Unexpected, "No data returned from load action");
}
+ loaded_ = true;
data_ready_ = true;
}
isc_throw(isc::Unexpected, "No data to install");
}
- data_ready_ = false;
ZoneTable* table(segment_->getHeader().getTable());
if (table == NULL) {
ZoneTable::AddResult result(table->addZone(segment_->getMemorySegment(),
rrclass_, origin_, zone_data_));
+ data_ready_ = false;
zone_data_ = result.zone_data;
}
void
ZoneWriterLocal::cleanup() {
// We eat the data (if any) now.
- data_ready_ = false;
if (zone_data_ != NULL) {
ZoneData::destroy(segment_->getMemorySegment(), zone_data_, rrclass_);
zone_data_ = NULL;
+ data_ready_ = false;
}
}
/// \param install_action The callback used to install the loaded zone.
/// \param rrclass The class of the zone.
ZoneWriterLocal(ZoneTableSegment* segment, const LoadAction& load_action,
- const dns::Name& name, const dns::RRClass& rrclass);
+ const dns::Name& name, const dns::RRClass& rrclass);
/// \brief Destructor
~ZoneWriterLocal();
/// \throw isc::Unexpected if it is called the second time in lifetime
/// of the object or if load() was not called previously or if
/// cleanup() was already called.
- /// \throw Whatever the install_action throws, it is propagated up.
virtual void install();
/// \brief Clean up memory.
EXPECT_NO_THROW(writer_->cleanup());
}
+// Check the strong exception guarantee - if it throws, nothing happened
+// to the content.
+TEST_F(ZoneWriterLocalTest, retry) {
+ load_throw_ = true;
+ EXPECT_THROW(writer_->load(), TestException);
+
+ load_called_ = load_throw_ = false;
+ EXPECT_NO_THROW(writer_->load());
+ EXPECT_TRUE(load_called_);
+
+ // The rest still works correctly
+ EXPECT_NO_THROW(writer_->install());
+ EXPECT_NO_THROW(writer_->cleanup());
+}
+
// Check the writer defends itsefl when load action returns NULL
TEST_F(ZoneWriterLocalTest, loadNull) {
load_null_ = true;