From: Michal 'vorner' Vaner Date: Thu, 25 Oct 2012 18:43:38 +0000 (+0200) Subject: [2209] Provide the callbacks to load data X-Git-Tag: trac2487_base~23^2~27^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f609865c302b87caa3f5721557b0e5491c3eba3e;p=thirdparty%2Fkea.git [2209] Provide the callbacks to load data So now the loading works correctly (at least as the tests say). --- diff --git a/src/lib/datasrc/client_list.cc b/src/lib/datasrc/client_list.cc index 744776b154..14ae96925d 100644 --- a/src/lib/datasrc/client_list.cc +++ b/src/lib/datasrc/client_list.cc @@ -19,12 +19,14 @@ #include "memory/memory_client.h" #include "memory/zone_table_segment.h" #include "memory/zone_writer.h" +#include "memory/zone_data_loader.h" #include "logger.h" #include #include #include #include +#include using namespace isc::data; using namespace isc::dns; @@ -378,6 +380,46 @@ ConfigurableClientList::reload(const Name& name) { return (ZONE_RELOADED); } +namespace { + +// We would like to use boost::bind for this. However, the loadZoneData takes +// a reference, while we have a shared pointer to the iterator -- and we need +// to keep it alive as long as the ZoneWriter is alive. Therefore we can't +// really just dereference it and pass it, since it would get destroyed once +// the getCachedZoneWriter would end. This class holds the shared pointer +// alive, otherwise is mostly simple. +// +// It might be doable with nested boost::bind, but it would probably look +// more awkward and complicated than this. +class IteratorLoader { +public: + IteratorLoader(const RRClass& rrclass, const Name& name, + const ZoneIteratorPtr& iterator) : + rrclass_(rrclass), + name_(name), + iterator_(iterator) + {} + memory::ZoneData* operator()(util::MemorySegment& segment) { + return (memory::loadZoneData(segment, rrclass_, name_, *iterator_)); + } +private: + const RRClass rrclass_; + const Name name_; + ZoneIteratorPtr iterator_; +}; + +// We can't use the loadZoneData function directly in boost::bind, since +// it is overloaded and the compiler can't choose the correct version +// reliably and fails. So we simply wrap it into an unique name. +memory::ZoneData* +loadZoneDataFromFile(util::MemorySegment& segment, const RRClass& rrclass, + const Name& name, const string& filename) +{ + return (memory::loadZoneData(segment, rrclass, name, filename)); +} + +} + ConfigurableClientList::ZoneWriterPair ConfigurableClientList::getCachedZoneWriter(const Name& name) { if (!allow_cache_) { @@ -405,7 +447,9 @@ ConfigurableClientList::getCachedZoneWriter(const Name& name) { if (!iterator) { isc_throw(isc::Unexpected, "Null iterator from " << name); } - // TODO + // And wrap the iterator into the correct functor (which + // keeps it alive as long as it is needed). + load_action = IteratorLoader(rrclass_, name, iterator); } else { // The MasterFiles special case const string filename(result.info->cache_->getFileName(name)); @@ -413,7 +457,9 @@ ConfigurableClientList::getCachedZoneWriter(const Name& name) { isc_throw(isc::Unexpected, "Confused about missing both filename " "and data source"); } - // TODO + // boost::bind is enough here. + load_action = boost::bind(loadZoneDataFromFile, _1, rrclass_, name, + filename); } return (ZoneWriterPair(ZONE_RELOADED, ZoneWriterPtr(result.info->cache_->getZoneTableSegment().