From: Michal 'vorner' Vaner Date: Mon, 8 Apr 2013 10:33:59 +0000 (+0200) Subject: [2871] The fake interface implemented X-Git-Tag: bind10-1.1.0beta2-release~8^2~10^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a16cb0089b11bb4a2cbc3230ee6870693c469fc7;p=thirdparty%2Fkea.git [2871] The fake interface implemented --- diff --git a/src/bin/resolver/bench/Makefile.am b/src/bin/resolver/bench/Makefile.am index 6f1740f619..7dad500825 100644 --- a/src/bin/resolver/bench/Makefile.am +++ b/src/bin/resolver/bench/Makefile.am @@ -20,3 +20,5 @@ resolver_bench_SOURCES += dummy_work.h dummy_work.cc resolver_bench_LDADD = $(GTEST_LDADD) resolver_bench_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la +resolver_bench_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la + diff --git a/src/bin/resolver/bench/fake_resolution.cc b/src/bin/resolver/bench/fake_resolution.cc index 18151db676..2fb6cf86c8 100644 --- a/src/bin/resolver/bench/fake_resolution.cc +++ b/src/bin/resolver/bench/fake_resolution.cc @@ -15,6 +15,10 @@ #include #include +#include + +#include +#include #include #include @@ -84,6 +88,85 @@ FakeQuery::performTask(const StepCallback& callback) { } } +FakeInterface::FakeInterface(size_t query_count) : + queries_(query_count) +{ + BOOST_FOREACH(FakeQueryPtr& query, queries_) { + query = FakeQueryPtr(new FakeQuery(*this)); + } +} + +void +FakeInterface::processEvents() { + service_.run_one(); +} + +namespace { + +void +processDone(bool* flag) { + *flag = true; +} + +} + +FakeQueryPtr +FakeInterface::receiveQuery() { + // Handle all the events that are already scheduled. + // As processEvents blocks until an event happens and we want to terminate + // if there are no events, we do a small trick. We schedule a timeout with + // 0 time. That'll place the event for it directly at the end of the queue. + // Then, we'll just call processEvents() until that event happens. + bool processed = false; + asiolink::IntervalTimer zero_timer(service_); + zero_timer.setup(boost::bind(&processDone, &processed), 0); + while (!processed) { + processEvents(); + } + + // Now, look if there are more queries to return. + if (queries_.empty()) { + return (FakeQueryPtr()); + } else { + // Take from the back. The order doesn't matter and it's faster from + // there. + FakeQueryPtr result(queries_.back()); + queries_.pop_back(); + return (result); + } +} + +class FakeInterface::UpstreamQuery { +public: + UpstreamQuery(FakeQuery* query, const FakeQuery::StepCallback& callback, + const boost::shared_ptr timer) : + query_(query), + callback_(callback), + timer_(timer) + {} + void operator()() { + query_->outstanding_ = false; + callback_(); + } +private: + FakeQuery* const query_; + const FakeQuery::StepCallback callback_; + // Just to hold it alive before the callback is called (or discarded for + // some reason, like destroying the service). + const boost::shared_ptr timer_; +}; + +void +FakeInterface::scheduleUpstreamAnswer(FakeQuery* query, + const FakeQuery::StepCallback& callback, + size_t msec) +{ + const boost::shared_ptr + timer(new asiolink::IntervalTimer(service_)); + UpstreamQuery q(query, callback, timer); + timer->setup(q, msec); +} + } } } diff --git a/src/bin/resolver/bench/fake_resolution.h b/src/bin/resolver/bench/fake_resolution.h index 290a715be0..0fc0b4032a 100644 --- a/src/bin/resolver/bench/fake_resolution.h +++ b/src/bin/resolver/bench/fake_resolution.h @@ -16,6 +16,7 @@ #define FAKE_RESOLUTION_H #include +#include #include #include @@ -80,15 +81,6 @@ private: friend class FakeInterface; /// \brief Constructor FakeQuery(FakeInterface& interface); - // The scheduled steps for this task. - typedef std::pair Step; - // The scheduled steps. Reversed (first to be done at the end), so we can - // pop_back() the completed steps. - std::vector steps_; - // The interface to schedule timeouts on. - FakeInterface* interface_; - // Is an upstream query outstanding? - bool outstanding_; public: /// \brief Is work on the query completely done? /// @@ -150,6 +142,16 @@ public: } interface_ = &dst_interface; } +private: + // The scheduled steps for this task. + typedef std::pair Step; + // The scheduled steps. Reversed (first to be done at the end), so we can + // pop_back() the completed steps. + std::vector steps_; + // The interface to schedule timeouts on. + FakeInterface* interface_; + // Is an upstream query outstanding? + bool outstanding_; }; typedef boost::shared_ptr FakeQueryPtr; @@ -174,12 +176,12 @@ typedef boost::shared_ptr FakeQueryPtr; /// in advance, on creation time. But you need to create all the needed /// interfaces from single thread and then distribute them to your threads. class FakeInterface { -private: - friend class FakeQuery; - void scheduleUpstreamAnswer(FakeQuery* query, - const FakeQuery::StepCallback& callback, - size_t msec); public: + /// \brief Constructor + /// + /// Initiarile the interface and create query_count queries for the + /// benchmark. They will be handed out one by one with receiveQuery(). + FakeInterface(size_t query_count); /// \brief Wait for answers from upstream servers. /// /// Wait until at least one "answer" comes from the remote server. This @@ -202,6 +204,14 @@ public: /// This returns a NULL pointer when there are no more queries to answer /// (the number designated for the benchmark was reached). FakeQueryPtr receiveQuery(); +private: + class UpstreamQuery; + friend class FakeQuery; + void scheduleUpstreamAnswer(FakeQuery* query, + const FakeQuery::StepCallback& callback, + size_t msec); + asiolink::IOService service_; + std::vector queries_; }; }