Commit cfbf803b authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2905] store an empty zone data in zone table as placeholder of broken zones.

parent 2afcb422
...@@ -40,7 +40,10 @@ void ...@@ -40,7 +40,10 @@ void
deleteZoneData(util::MemorySegment* mem_sgmt, ZoneData* zone_data, deleteZoneData(util::MemorySegment* mem_sgmt, ZoneData* zone_data,
RRClass rrclass) 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); ZoneData::destroy(*mem_sgmt, zone_data, rrclass);
} }
} }
...@@ -49,21 +52,30 @@ typedef boost::function<void(ZoneData*)> ZoneDataDeleterType; ...@@ -49,21 +52,30 @@ typedef boost::function<void(ZoneData*)> ZoneDataDeleterType;
ZoneTable* ZoneTable*
ZoneTable::create(util::MemorySegment& mem_sgmt, const RRClass& zone_class) { ZoneTable::create(util::MemorySegment& mem_sgmt, const RRClass& zone_class) {
SegmentObjectHolder<ZoneTableTree, ZoneDataDeleterType> holder( // Create a placeholder "null" zone data
SegmentObjectHolder<ZoneData, RRClass> zdholder(mem_sgmt, zone_class);
zdholder.set(ZoneData::create(mem_sgmt));
// create and setup the tree for the table.
SegmentObjectHolder<ZoneTableTree, ZoneDataDeleterType> tree_holder(
mem_sgmt, boost::bind(deleteZoneData, &mem_sgmt, _1, zone_class)); 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)); 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); return (zone_table);
} }
void void
ZoneTable::destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable) ZoneTable::destroy(util::MemorySegment& mem_sgmt, ZoneTable* ztable) {
{
ZoneTableTree::destroy(mem_sgmt, ztable->zones_.get(), ZoneTableTree::destroy(mem_sgmt, ztable->zones_.get(),
boost::bind(deleteZoneData, &mem_sgmt, _1, boost::bind(deleteZoneData, &mem_sgmt, _1,
ztable->rrclass_)); ztable->rrclass_));
ZoneData::destroy(mem_sgmt, ztable->null_zone_data_.get(),
ztable->rrclass_);
mem_sgmt.deallocate(ztable, sizeof(ZoneTable)); mem_sgmt.deallocate(ztable, sizeof(ZoneTable));
} }
......
...@@ -99,13 +99,13 @@ private: ...@@ -99,13 +99,13 @@ private:
/// An object of this class is always expected to be created by the /// An object of this class is always expected to be created by the
/// allocator (\c create()), so the constructor is hidden as private. /// allocator (\c create()), so the constructor is hidden as private.
/// ///
/// This constructor internally involves resource allocation, and if /// This constructor never throws.
/// it fails, a corresponding standard exception will be thrown. ZoneTable(const dns::RRClass& rrclass, ZoneTableTree* zones,
/// It never throws an exception otherwise. ZoneData* null_zone_data) :
ZoneTable(const dns::RRClass& rrclass, ZoneTableTree* zones) :
rrclass_(rrclass), rrclass_(rrclass),
zone_count_(0), zone_count_(0),
zones_(zones) zones_(zones),
null_zone_data_(null_zone_data)
{} {}
public: public:
...@@ -213,6 +213,9 @@ private: ...@@ -213,6 +213,9 @@ private:
const dns::RRClass rrclass_; const dns::RRClass rrclass_;
size_t zone_count_; size_t zone_count_;
boost::interprocess::offset_ptr<ZoneTableTree> zones_; boost::interprocess::offset_ptr<ZoneTableTree> zones_;
// this is a shared placeholder for broken zones
boost::interprocess::offset_ptr<ZoneData> null_zone_data_;
}; };
} }
} }
......
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