From: Michal 'vorner' Vaner Date: Fri, 10 May 2013 11:37:12 +0000 (+0200) Subject: [2836] Make segment holder survive relocation X-Git-Tag: bind10-1.2.0beta1-release~457^2~28 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2f220f9ff1a51348ea225d72a75d58d5d81031aa;p=thirdparty%2Fkea.git [2836] Make segment holder survive relocation Let the SegmentObjectHolder store the object's address in the segment's named addresses, so it moves correctly when the segment is relocated. --- diff --git a/src/lib/datasrc/memory/Makefile.am b/src/lib/datasrc/memory/Makefile.am index c0ee688a89..27c2de3817 100644 --- a/src/lib/datasrc/memory/Makefile.am +++ b/src/lib/datasrc/memory/Makefile.am @@ -17,6 +17,7 @@ libdatasrc_memory_la_SOURCES += rdata_serialization.h rdata_serialization.cc libdatasrc_memory_la_SOURCES += zone_data.h zone_data.cc libdatasrc_memory_la_SOURCES += rrset_collection.h rrset_collection.cc libdatasrc_memory_la_SOURCES += segment_object_holder.h +libdatasrc_memory_la_SOURCES += segment_object_holder.cc libdatasrc_memory_la_SOURCES += logger.h logger.cc libdatasrc_memory_la_SOURCES += zone_table.h zone_table.cc libdatasrc_memory_la_SOURCES += zone_finder.h zone_finder.cc diff --git a/src/lib/datasrc/memory/segment_object_holder.cc b/src/lib/datasrc/memory/segment_object_holder.cc new file mode 100644 index 0000000000..9ca9d3c325 --- /dev/null +++ b/src/lib/datasrc/memory/segment_object_holder.cc @@ -0,0 +1,34 @@ +// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THIS SOFTWARE. + +#include "segment_object_holder.h" + +#include + +namespace isc { +namespace datasrc { +namespace memory { +namespace detail { + +std::string +getNextHolderName() { + static size_t index = 0; + return ("Segment object holder auto name " + + boost::lexical_cast(index ++)); +} + +} +} +} +} diff --git a/src/lib/datasrc/memory/segment_object_holder.h b/src/lib/datasrc/memory/segment_object_holder.h index 384f4ef45f..e1629d0154 100644 --- a/src/lib/datasrc/memory/segment_object_holder.h +++ b/src/lib/datasrc/memory/segment_object_holder.h @@ -1,4 +1,4 @@ -// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above @@ -16,12 +16,22 @@ #define DATASRC_MEMORY_SEGMENT_OBJECT_HOLDER_H 1 #include +#include namespace isc { namespace datasrc { namespace memory { namespace detail { +// Internal function to get next yet unused name of segment holder. +// We need the names of holders to be unique per segment at any given +// momemnt. This just keeps incrementing number after a prefix with +// each call, it should be enough (the holder should no longer be +// alive when the counter wraps around, if that ever happens with +// presumably 64bit counters). +std::string +getNextHolderName(); + // A simple holder to create and use some objects in this implementation // in an exception safe manner. It works like std::auto_ptr but much // more simplified. @@ -32,23 +42,41 @@ template class SegmentObjectHolder { public: SegmentObjectHolder(util::MemorySegment& mem_sgmt, T* obj, ARG_T arg) : - mem_sgmt_(mem_sgmt), obj_(obj), arg_(arg) - {} + mem_sgmt_(mem_sgmt), arg_(arg), + holder_name_(getNextHolderName()), holding_(true) + { + mem_sgmt_.setNamedAddress(holder_name_.c_str(), obj); + } ~SegmentObjectHolder() { - if (obj_ != NULL) { - T::destroy(mem_sgmt_, obj_, arg_); + if (holding_) { + // Use release, as it removes the stored address from segment + T* obj = release(); + T::destroy(mem_sgmt_, obj, arg_); + } + } + T* get() { + if (holding_) { + return (static_cast( + mem_sgmt_.getNamedAddress(holder_name_.c_str()))); + } else { + return (NULL); } } - T* get() { return (obj_); } T* release() { - T* ret = obj_; - obj_ = NULL; - return (ret); + if (holding_) { + T* obj = get(); + mem_sgmt_.clearNamedAddress(holder_name_.c_str()); + holding_ = false; + return (obj); + } else { + return (NULL); + } } private: util::MemorySegment& mem_sgmt_; - T* obj_; ARG_T arg_; + const std::string holder_name_; + bool holding_; }; } // detail