From: JINMEI Tatuya Date: Sat, 18 May 2013 01:56:08 +0000 (-0700) Subject: [2905] store an empty zone data in zone table as placeholder of broken zones. X-Git-Tag: bind10-1.2.0beta1-release~434^2~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cfbf803bb49ad944bef4070fec9f2c999a98cb78;p=thirdparty%2Fkea.git [2905] store an empty zone data in zone table as placeholder of broken zones. --- diff --git a/src/lib/datasrc/memory/zone_table.cc b/src/lib/datasrc/memory/zone_table.cc index 2ecf14aa3c..0cd6edf5ba 100644 --- a/src/lib/datasrc/memory/zone_table.cc +++ b/src/lib/datasrc/memory/zone_table.cc @@ -40,7 +40,10 @@ void deleteZoneData(util::MemorySegment* mem_sgmt, ZoneData* zone_data, RRClass rrclass) { - if (zone_data != NULL) { + // We shouldn't delete empty zone data here; the only empty zone + // that can be passed here is the placeholder for broken zones maintained + // in the zone table. It will stay there until the table is destroyed. + if (zone_data && !zone_data->isEmpty()) { ZoneData::destroy(*mem_sgmt, zone_data, rrclass); } } @@ -49,21 +52,30 @@ typedef boost::function ZoneDataDeleterType; ZoneTable* ZoneTable::create(util::MemorySegment& mem_sgmt, const RRClass& zone_class) { - SegmentObjectHolder holder( + // Create a placeholder "null" zone data + SegmentObjectHolder zdholder(mem_sgmt, zone_class); + zdholder.set(ZoneData::create(mem_sgmt)); + + // create and setup the tree for the table. + SegmentObjectHolder tree_holder( mem_sgmt, boost::bind(deleteZoneData, &mem_sgmt, _1, zone_class)); - holder.set(ZoneTableTree::create(mem_sgmt)); + tree_holder.set(ZoneTableTree::create(mem_sgmt)); void* p = mem_sgmt.allocate(sizeof(ZoneTable)); - ZoneTable* zone_table = new(p) ZoneTable(zone_class, holder.get()); - holder.release(); + + // Build zone table with the created objects. Its constructor doesn't + // throw, so we can release them from the holder at this point. + ZoneTable* zone_table = new(p) ZoneTable(zone_class, tree_holder.release(), + zdholder.release()); return (zone_table); } void -ZoneTable::destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable) -{ +ZoneTable::destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable) { ZoneTableTree::destroy(mem_sgmt, ztable->zones_.get(), boost::bind(deleteZoneData, &mem_sgmt, _1, ztable->rrclass_)); + ZoneData::destroy(mem_sgmt, ztable->null_zone_data_.get(), + ztable->rrclass_); mem_sgmt.deallocate(ztable, sizeof(ZoneTable)); } diff --git a/src/lib/datasrc/memory/zone_table.h b/src/lib/datasrc/memory/zone_table.h index d3bf9031f0..7211173079 100644 --- a/src/lib/datasrc/memory/zone_table.h +++ b/src/lib/datasrc/memory/zone_table.h @@ -99,13 +99,13 @@ private: /// An object of this class is always expected to be created by the /// allocator (\c create()), so the constructor is hidden as private. /// - /// This constructor internally involves resource allocation, and if - /// it fails, a corresponding standard exception will be thrown. - /// It never throws an exception otherwise. - ZoneTable(const dns::RRClass& rrclass, ZoneTableTree* zones) : + /// This constructor never throws. + ZoneTable(const dns::RRClass& rrclass, ZoneTableTree* zones, + ZoneData* null_zone_data) : rrclass_(rrclass), zone_count_(0), - zones_(zones) + zones_(zones), + null_zone_data_(null_zone_data) {} public: @@ -213,6 +213,9 @@ private: const dns::RRClass rrclass_; size_t zone_count_; boost::interprocess::offset_ptr zones_; + + // this is a shared placeholder for broken zones + boost::interprocess::offset_ptr null_zone_data_; }; } }