[svn] commit: r3406 - /branches/vorner-recursor-timeouts/src/lib/asiolink/udpdns.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Sun Oct 31 18:49:03 UTC 2010
Author: vorner
Date: Sun Oct 31 18:49:03 2010
New Revision: 3406
Log:
Implement timeouts in UDPQuery
Modified:
branches/vorner-recursor-timeouts/src/lib/asiolink/udpdns.cc
Modified: branches/vorner-recursor-timeouts/src/lib/asiolink/udpdns.cc
==============================================================================
--- branches/vorner-recursor-timeouts/src/lib/asiolink/udpdns.cc (original)
+++ branches/vorner-recursor-timeouts/src/lib/asiolink/udpdns.cc Sun Oct 31 18:49:03 2010
@@ -23,8 +23,10 @@
#include <boost/bind.hpp>
#include <asio.hpp>
+#include <asio/deadline_timer.hpp>
#include <boost/shared_ptr.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <dns/buffer.h>
#include <dns/message.h>
@@ -179,6 +181,9 @@
OutputBufferPtr msgbuf;
boost::shared_array<char> data;
Callback* callback;
+ bool stopped;
+ deadline_timer timer;
+ int timeout;
Priv(io_service& service, const udp::socket::protocol_type& protocol,
const Question &q, OutputBufferPtr b, Callback *c) :
@@ -186,7 +191,9 @@
question(q),
buffer(b),
msgbuf(new OutputBuffer(512)),
- callback(c)
+ callback(c),
+ stopped(false),
+ timer(service)
{ }
};
@@ -201,15 +208,16 @@
callback))
{
priv->remote = UDPEndpoint(addr, port).getASIOEndpoint();
+ priv->timeout = timeout;
}
/// The function operator is implemented with the "stackless coroutine"
/// pattern; see internal/coroutine.h for details.
void
UDPQuery::operator()(error_code ec, size_t length) {
- if (ec) {
+ if (ec || priv->stopped) {
return;
- }
+ }
CORO_REENTER (this) {
/// Generate the upstream query and render it to wire format
@@ -228,6 +236,15 @@
msg.toWire(renderer);
}
+ // If we timeout, we stop, which will shutdown everything and
+ // cancel all other attempts to run inside the coroutine
+ if (priv->timeout != -1) {
+ priv->timer.expires_from_now(boost::posix_time::milliseconds(
+ priv->timeout));
+ priv->timer.async_wait(boost::bind(&UDPQuery::stop, *this,
+ TIME_OUT));
+ }
+
// Begin an asynchronous send, and then yield. When the
// send completes, we will resume immediately after this point.
CORO_YIELD priv->socket.async_send_to(buffer(priv->msgbuf->getData(),
@@ -250,8 +267,21 @@
priv->buffer->writeData(priv->data.get(), length);
/// We are done
- (*priv->callback)(SUCCESS);
- }
-}
-
-}
+ stop(SUCCESS);
+ }
+}
+
+void
+UDPQuery::stop(Result result) {
+ if (!priv->stopped) {
+ priv->stopped = true;
+ priv->socket.cancel();
+ priv->socket.close();
+ priv->timer.cancel();
+ if (priv->callback) {
+ (*priv->callback)(result);
+ }
+ }
+}
+
+}
More information about the bind10-changes
mailing list