BIND 10 trac2871, updated. e4870b2ea373a314214f1ff575aa675496557b00 [2738] Tweak the times and iteration counts
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Apr 8 12:17:37 UTC 2013
The branch, trac2871 has been updated
via e4870b2ea373a314214f1ff575aa675496557b00 (commit)
via 135070d34df3a8c70cfaec68fcdd43704e017fb7 (commit)
via e893a8d8b65af8f4b4d01ddf0388fb2bceb52ea0 (commit)
via ef8e4e281a59bd4e3f5396533f96e54b7ffd1434 (commit)
from bcabe81c90f6e6294b714b4aef589f60f6b6cca1 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit e4870b2ea373a314214f1ff575aa675496557b00
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Mon Apr 8 14:17:09 2013 +0200
[2738] Tweak the times and iteration counts
So even the naive approach terminates some day.
commit 135070d34df3a8c70cfaec68fcdd43704e017fb7
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Mon Apr 8 14:15:45 2013 +0200
[2738] Don't preserve pointers to stack
It seems the boost::function created from functor takes just the
reference. This led to taking address of temporary and failing later on.
Allocate new object manually and delete it after it was used.
commit e893a8d8b65af8f4b4d01ddf0388fb2bceb52ea0
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Mon Apr 8 14:14:46 2013 +0200
[2738] Use IOService::post
Instead of abusing the timer with 0 timeout, which is rejected.
commit ef8e4e281a59bd4e3f5396533f96e54b7ffd1434
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Mon Apr 8 13:37:55 2013 +0200
[2871] IOService::post()
To execute a callback later, from the event loop. This is to be used in
the fake resolution, instead of timer with 0 timeout (which doesn't
work, we are strict with asserting invalid parameters).
-----------------------------------------------------------------------
Summary of changes:
src/bin/resolver/bench/fake_resolution.cc | 34 +++++++++---------
src/bin/resolver/bench/main.cc | 4 +--
src/lib/asiolink/io_service.cc | 8 +++++
src/lib/asiolink/io_service.h | 13 +++++++
src/lib/asiolink/tests/Makefile.am | 1 +
src/lib/asiolink/tests/io_service_unittest.cc | 48 +++++++++++++++++++++++++
6 files changed, 89 insertions(+), 19 deletions(-)
create mode 100644 src/lib/asiolink/tests/io_service_unittest.cc
-----------------------------------------------------------------------
diff --git a/src/bin/resolver/bench/fake_resolution.cc b/src/bin/resolver/bench/fake_resolution.cc
index 2fb6cf8..a538302 100644
--- a/src/bin/resolver/bench/fake_resolution.cc
+++ b/src/bin/resolver/bench/fake_resolution.cc
@@ -28,11 +28,11 @@ namespace bench {
// Parameters of the generated queries.
// How much work is each operation?
-const size_t parse_size = 10000000;
-const size_t render_size = 10000000;
-const size_t send_size = 100000;
-const size_t cache_read_size = 1000000;
-const size_t cache_write_size = 1000000;
+const size_t parse_size = 100000;
+const size_t render_size = 100000;
+const size_t send_size = 1000;
+const size_t cache_read_size = 10000;
+const size_t cache_write_size = 10000;
// How large a change is to terminate in this iteration (either by getting
// the complete answer, or by finding it in the cache). With 0.5, half the
// queries are found in the cache directly. Half of the rest needs just one
@@ -41,7 +41,7 @@ const float chance_complete = 0.5;
// Number of milliseconds an upstream query can take. It picks a random number
// in between.
const size_t upstream_time_min = 2;
-const size_t upstream_time_max = 30;
+const size_t upstream_time_max = 50;
FakeQuery::FakeQuery(FakeInterface& interface) :
interface_(&interface),
@@ -52,7 +52,7 @@ FakeQuery::FakeQuery(FakeInterface& interface) :
steps_.push_back(Step(Compute, parse_size));
// Look into the cache if it is there
steps_.push_back(Step(CacheRead, cache_read_size));
- while (1.0 * random() / RAND_MAX > chance_complete) {
+ while ((1.0 * random()) / RAND_MAX > chance_complete) {
// Needs another step of recursion. Render the upstream query.
steps_.push_back(Step(Compute, render_size));
// Send it and wait for the answer.
@@ -114,12 +114,11 @@ 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.
+ // if there are no events, we do a small trick. We post an event to the end
+ // of the queue and work until it is found. This should process all the
+ // events that were there already.
bool processed = false;
- asiolink::IntervalTimer zero_timer(service_);
- zero_timer.setup(boost::bind(&processDone, &processed), 0);
+ service_.post(boost::bind(&processDone, &processed));
while (!processed) {
processEvents();
}
@@ -144,15 +143,16 @@ public:
callback_(callback),
timer_(timer)
{}
- void operator()() {
+ void trigger() {
query_->outstanding_ = false;
callback_();
+ // We are not needed any more.
+ delete this;
}
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).
+ // Just to hold it alive before the callback is called.
const boost::shared_ptr<asiolink::IntervalTimer> timer_;
};
@@ -163,8 +163,8 @@ FakeInterface::scheduleUpstreamAnswer(FakeQuery* query,
{
const boost::shared_ptr<asiolink::IntervalTimer>
timer(new asiolink::IntervalTimer(service_));
- UpstreamQuery q(query, callback, timer);
- timer->setup(q, msec);
+ UpstreamQuery* q(new UpstreamQuery(query, callback, timer));
+ timer->setup(boost::bind(&UpstreamQuery::trigger, q), msec);
}
}
diff --git a/src/bin/resolver/bench/main.cc b/src/bin/resolver/bench/main.cc
index 81d9129..3007c40 100644
--- a/src/bin/resolver/bench/main.cc
+++ b/src/bin/resolver/bench/main.cc
@@ -16,12 +16,12 @@
#include <bench/benchmark.h>
-const size_t count = 100000; // TODO: We may want to read this from argv.
+const size_t count = 1000; // TODO: We may want to read this from argv.
int main(int, const char**) {
// Run the naive implementation
isc::resolver::bench::NaiveResolver naive_resolver(count);
isc::bench::BenchMark<isc::resolver::bench::NaiveResolver>
- (count, naive_resolver, true);
+ (1, naive_resolver, true);
return 0;
}
diff --git a/src/lib/asiolink/io_service.cc b/src/lib/asiolink/io_service.cc
index 15fad0c..ad4ae94 100644
--- a/src/lib/asiolink/io_service.cc
+++ b/src/lib/asiolink/io_service.cc
@@ -63,6 +63,9 @@ public:
/// It will eventually be removed once the wrapper interface is
/// generalized.
asio::io_service& get_io_service() { return io_service_; };
+ void post(const boost::function<void ()>& callback) {
+ io_service_.post(callback);
+ }
private:
asio::io_service io_service_;
asio::io_service::work work_;
@@ -96,5 +99,10 @@ IOService::get_io_service() {
return (io_impl_->get_io_service());
}
+void
+IOService::post(const boost::function<void ()>& callback) {
+ return (io_impl_->post(callback));
+}
+
} // namespace asiolink
} // namespace isc
diff --git a/src/lib/asiolink/io_service.h b/src/lib/asiolink/io_service.h
index e0198dd..7e0da8f 100644
--- a/src/lib/asiolink/io_service.h
+++ b/src/lib/asiolink/io_service.h
@@ -15,6 +15,8 @@
#ifndef ASIOLINK_IO_SERVICE_H
#define ASIOLINK_IO_SERVICE_H 1
+#include <boost/function.hpp>
+
namespace asio {
class io_service;
}
@@ -70,6 +72,17 @@ public:
/// generalized.
asio::io_service& get_io_service();
+ /// \brief Post a callback to the end of the queue.
+ ///
+ /// Requests the callback be called sometime later. It is not guaranteed
+ /// by the underlying asio, but it can reasonably be expected the callback
+ /// is put to the end of the callback queue. It is not called from within
+ /// this function.
+ ///
+ /// It may be used to implement "background" work, for example (doing stuff
+ /// by small bits that are called from time to time).
+ void post(const boost::function<void ()>& callback);
+
private:
IOServiceImpl* io_impl_;
};
diff --git a/src/lib/asiolink/tests/Makefile.am b/src/lib/asiolink/tests/Makefile.am
index b401834..70b94dc 100644
--- a/src/lib/asiolink/tests/Makefile.am
+++ b/src/lib/asiolink/tests/Makefile.am
@@ -33,6 +33,7 @@ run_unittests_SOURCES += tcp_endpoint_unittest.cc
run_unittests_SOURCES += tcp_socket_unittest.cc
run_unittests_SOURCES += udp_endpoint_unittest.cc
run_unittests_SOURCES += udp_socket_unittest.cc
+run_unittests_SOURCES += io_service_unittest.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
diff --git a/src/lib/asiolink/tests/io_service_unittest.cc b/src/lib/asiolink/tests/io_service_unittest.cc
new file mode 100644
index 0000000..2fe4f12
--- /dev/null
+++ b/src/lib/asiolink/tests/io_service_unittest.cc
@@ -0,0 +1,48 @@
+// 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 <asiolink/io_service.h>
+
+#include <gtest/gtest.h>
+#include <boost/bind.hpp>
+#include <vector>
+
+using namespace isc::asiolink;
+
+namespace {
+
+void
+postedEvent(std::vector<int>* destination, int value) {
+ destination->push_back(value);
+}
+
+// Check the posted events are called, in the same order they are posted.
+TEST(IOService, post) {
+ std::vector<int> called;
+ IOService service;
+ // Post two events
+ service.post(boost::bind(&postedEvent, &called, 1));
+ service.post(boost::bind(&postedEvent, &called, 2));
+ // They have not yet been called
+ EXPECT_TRUE(called.empty());
+ // Process two events
+ service.run_one();
+ service.run_one();
+ // Both events were called in the right order
+ ASSERT_EQ(2, called.size());
+ EXPECT_EQ(1, called[0]);
+ EXPECT_EQ(2, called[1]);
+}
+
+}
More information about the bind10-changes
mailing list