Commit 84e0dc1b authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

[2207] Provide strong exception guarantee

parent 2530e97e
......@@ -48,7 +48,6 @@ ZoneWriterLocal::load() {
if (loaded_) {
isc_throw(isc::Unexpected, "Trying to load twice");
}
loaded_ = true;
zone_data_ = load_action_(segment_->getMemorySegment());
......@@ -57,6 +56,7 @@ ZoneWriterLocal::load() {
isc_throw(isc::Unexpected, "No data returned from load action");
}
loaded_ = true;
data_ready_ = true;
}
......@@ -66,7 +66,6 @@ ZoneWriterLocal::install() {
isc_throw(isc::Unexpected, "No data to install");
}
data_ready_ = false;
ZoneTable* table(segment_->getHeader().getTable());
if (table == NULL) {
......@@ -75,17 +74,18 @@ ZoneWriterLocal::install() {
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;
}
}
......
......@@ -42,7 +42,7 @@ public:
/// \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();
......@@ -65,7 +65,6 @@ public:
/// \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.
......
......@@ -190,6 +190,21 @@ TEST_F(ZoneWriterLocalTest, loadThrows) {
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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment