BIND 10 trac598_new, updated. 32872f1e745f45d1c0e84943cf57ad985a925f3e [trac598_new] Rewrite the stop logic of forward query.
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed May 11 09:55:28 UTC 2011
The branch, trac598_new has been updated
via 32872f1e745f45d1c0e84943cf57ad985a925f3e (commit)
from 4569c1b87f5d04f663e1c8e2813d090a78dd9e40 (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 32872f1e745f45d1c0e84943cf57ad985a925f3e
Author: zhanglikun <zhanglikun at cnnic.cn>
Date: Wed May 11 17:55:24 2011 +0800
[trac598_new] Rewrite the stop logic of forward query.
-----------------------------------------------------------------------
Summary of changes:
src/lib/resolve/recursive_query.cc | 79 ++++++++++++++++++++++--------------
1 files changed, 49 insertions(+), 30 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/resolve/recursive_query.cc b/src/lib/resolve/recursive_query.cc
index ef3b259..0f22fdd 100644
--- a/src/lib/resolve/recursive_query.cc
+++ b/src/lib/resolve/recursive_query.cc
@@ -778,10 +778,14 @@ private:
asio::deadline_timer client_timer;
asio::deadline_timer lookup_timer;
- // If we have a client timeout, we send back an answer, but don't
- // stop. We use this variable to make sure we don't send another
- // answer if we do find one later (or if we have a lookup_timeout)
- bool answer_sent_;
+ // Make FowardQuery deletes itself safely. for more information see
+ // the comments of outstanding_events in RunningQuery.
+ size_t outstanding_events_;
+
+ // If we have a client timeout, we call back with a failure message,
+ // but we do not stop yet. We use this variable to make sure we
+ // don't call back a second time later
+ bool callback_called_;
// send the query to the server.
void send(IOFetch::Protocol protocol = IOFetch::UDP) {
@@ -791,6 +795,7 @@ private:
ConstQuestionPtr question = *(query_message_->beginQuestion());
dlog("Sending upstream query (" + question->toText() +
") to " + upstream_->at(serverIndex).first);
+ ++outstanding_events_;
// Forward the query, create the IOFetch with
// query message, so that query flags can be forwarded
// together.
@@ -819,37 +824,57 @@ public:
query_timeout_(query_timeout),
client_timer(io.get_io_service()),
lookup_timer(io.get_io_service()),
- answer_sent_(false)
+ outstanding_events_(0)
{
// Setup the timer to stop trying (lookup_timeout)
if (lookup_timeout >= 0) {
lookup_timer.expires_from_now(
boost::posix_time::milliseconds(lookup_timeout));
- lookup_timer.async_wait(boost::bind(&ForwardQuery::stop, this, false));
+ ++outstanding_events_;
+ lookup_timer.async_wait(boost::bind(&ForwardQuery::lookupTimeout, this));
}
// Setup the timer to send an answer (client_timeout)
if (client_timeout >= 0) {
client_timer.expires_from_now(
boost::posix_time::milliseconds(client_timeout));
+ ++outstanding_events_;
client_timer.async_wait(boost::bind(&ForwardQuery::clientTimeout, this));
}
send();
}
+ virtual void lookupTimeout() {
+ callCallback(false);
+ assert(outstanding_events_ > 0);
+ --outstanding_events_;
+ stop();
+ }
+
virtual void clientTimeout() {
- // Return a SERVFAIL, but do not stop until
- // we have an answer or timeout ourselves
- isc::resolve::makeErrorMessage(answer_message_,
- Rcode::SERVFAIL());
- if (!answer_sent_) {
- answer_sent_ = true;
- resolvercallback_->success(answer_message_);
+ callCallback(false);
+ assert(outstanding_events_ > 0);
+ --outstanding_events_;
+ stop();
+ }
+
+ // If the callback has not been called yet, call it now
+ // If success is true, we call 'success' with our answer_message
+ // If it is false, we call failure()
+ void callCallback(bool success) {
+ if (!callback_called_) {
+ callback_called_ = true;
+ isc::resolve::makeErrorMessage(answer_message_, Rcode::SERVFAIL());
+ if (success) {
+ resolvercallback_->success(answer_message_);
+ } else {
+ resolvercallback_->failure();
+ }
}
}
- virtual void stop(bool resume) {
+ virtual void stop() {
// if we cancel our timers, we will still get an event for
// that, so we cannot delete ourselves just yet (those events
// would be bound to a deleted object)
@@ -857,36 +882,30 @@ public:
// here again.
// same goes if we have an outstanding query (can't delete
// until that one comes back to us)
- if (resume && !answer_sent_) {
- answer_sent_ = true;
- resolvercallback_->success(answer_message_);
- } else {
- resolvercallback_->failure();
- }
- if (lookup_timer.cancel() != 0) {
- return;
- }
- if (client_timer.cancel() != 0) {
+ lookup_timer.cancel();
+ client_timer.cancel();
+ if (outstanding_events_ > 0) {
return;
+ } else {
+ delete this;
}
-
- delete this;
}
// This function is used as callback from DNSQuery.
virtual void operator()(IOFetch::Result result) {
// XXX is this the place for TCP retry?
+ assert(outstanding_events_ > 0);
+ --outstanding_events_;
if (result != IOFetch::TIME_OUT) {
// we got an answer
Message incoming(Message::PARSE);
InputBuffer ibuf(buffer_->getData(), buffer_->getLength());
incoming.fromWire(ibuf);
isc::resolve::copyResponseMessage(incoming, answer_message_);
- stop(true);
- } else {
- // timeout, give up for now
- stop(false);
+ callCallback(true);
}
+
+ stop();
}
};
More information about the bind10-changes
mailing list