[svn] commit: r3404 - in /branches/vorner-recursor-timeouts/src/lib/asiolink: internal/udpdns.h udpdns.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Sun Oct 31 17:34:57 UTC 2010
Author: vorner
Date: Sun Oct 31 17:34:56 2010
New Revision: 3404
Log:
Move members of asiolink::UDPQuery inside Priv
This is not because of stable ABI, but because the class is copyed a lot
and it would need many shared pointers.
Modified:
branches/vorner-recursor-timeouts/src/lib/asiolink/internal/udpdns.h
branches/vorner-recursor-timeouts/src/lib/asiolink/udpdns.cc
Modified: branches/vorner-recursor-timeouts/src/lib/asiolink/internal/udpdns.h
==============================================================================
--- branches/vorner-recursor-timeouts/src/lib/asiolink/internal/udpdns.h (original)
+++ branches/vorner-recursor-timeouts/src/lib/asiolink/internal/udpdns.h Sun Oct 31 17:34:56 2010
@@ -218,36 +218,14 @@
private:
enum { MAX_LENGTH = 4096 };
- // The \c UDPQuery coroutine never forks, but it is copied whenever
- // it calls an async_*() function, so it's best to keep copy overhead
- // small by using pointers or references when possible. However, this
- // is not always possible.
- //
- // Socket used to for upstream queries. Created in the
- // constructor and stored in a shared_ptr because socket objects
- // are not copyable.
- boost::shared_ptr<asio::ip::udp::socket> socket_;
-
- // The remote endpoint. Instantiated in the constructor. Not
- // stored as a shared_ptr because copy overhead of an endpoint
- // object is no larger than that of a shared_ptr.
- asio::ip::udp::endpoint remote_;
-
- // The question being answered. Copied rather than referenced
- // because the object that created it is not guaranteed to persist.
- isc::dns::Question question_;
-
- // The output buffer supplied by the caller. The resposne frmo
- // the upstream server will be copied here.
- isc::dns::OutputBufferPtr buffer_;
-
- // These are allocated for each new query and are stored as
- // shared pointers to minimize copy overhead.
- isc::dns::OutputBufferPtr msgbuf_;
- boost::shared_array<char> data_;
-
- // This will be called when we are done.
- Callback* callback_;
+ /**
+ * Private data. They are not private because of stability of the
+ * interface (this is private class anyway), but because this class
+ * will be copyed often and we want to keep the same data between
+ * the coroutines.
+ */
+ struct Priv;
+ boost::shared_ptr<Priv> priv;
};
}
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 17:34:56 2010
@@ -171,18 +171,36 @@
io_.post(*this);
}
+struct UDPQuery::Priv {
+ udp::socket socket;
+ udp::endpoint remote;
+ Question question;
+ OutputBufferPtr buffer;
+ OutputBufferPtr msgbuf;
+ boost::shared_array<char> data;
+ Callback* callback;
+
+ Priv(io_service& service, const udp::socket::protocol_type& protocol,
+ const Question &q, OutputBufferPtr b, Callback *c) :
+ socket(service, protocol),
+ question(q),
+ buffer(b),
+ msgbuf(new OutputBuffer(512)),
+ callback(c)
+ { }
+};
+
/// The following functions implement the \c UDPQuery class.
///
/// The constructor
UDPQuery::UDPQuery(io_service& io_service,
const Question& q, const IOAddress& addr, uint16_t port,
OutputBufferPtr buffer, Callback *callback, int timeout) :
- question_(q), buffer_(buffer), callback_(callback)
+ priv(new Priv(io_service,
+ addr.getFamily() == AF_INET ? udp::v4() : udp::v6(), q, buffer,
+ callback))
{
- udp proto = (addr.getFamily() == AF_INET) ? udp::v4() : udp::v6();
- socket_.reset(new udp::socket(io_service, proto));
- msgbuf_.reset(new OutputBuffer(512));
- remote_ = UDPEndpoint(addr, port).getASIOEndpoint();
+ priv->remote = UDPEndpoint(addr, port).getASIOEndpoint();
}
/// The function operator is implemented with the "stackless coroutine"
@@ -205,35 +223,34 @@
msg.setOpcode(Opcode::QUERY());
msg.setRcode(Rcode::NOERROR());
msg.setHeaderFlag(MessageFlag::RD());
- msg.addQuestion(question_);
- MessageRenderer renderer(*msgbuf_);
+ msg.addQuestion(priv->question);
+ MessageRenderer renderer(*priv->msgbuf);
msg.toWire(renderer);
}
// Begin an asynchronous send, and then yield. When the
// send completes, we will resume immediately after this point.
- CORO_YIELD socket_->async_send_to(buffer(msgbuf_->getData(),
- msgbuf_->getLength()),
- remote_, *this);
+ CORO_YIELD priv->socket.async_send_to(buffer(priv->msgbuf->getData(),
+ priv->msgbuf->getLength()), priv->remote, *this);
/// Allocate space for the response. (XXX: This should be
/// optimized by maintaining a free list of pre-allocated blocks)
- data_.reset(new char[MAX_LENGTH]);
+ priv->data.reset(new char[MAX_LENGTH]);
/// Begin an asynchronous receive, and yield. When the receive
/// completes, we will resume immediately after this point.
- CORO_YIELD socket_->async_receive_from(buffer(data_.get(), MAX_LENGTH),
- remote_, *this);
+ CORO_YIELD priv->socket.async_receive_from(buffer(priv->data.get(),
+ MAX_LENGTH), priv->remote, *this);
/// Copy the answer into the response buffer. (XXX: If the
/// OutputBuffer object were made to meet the requirements of
/// a MutableBufferSequence, then it could be written to directly
/// by async_recieve_from() and this additional copy step would
/// be unnecessary.)
- buffer_->writeData(data_.get(), length);
+ priv->buffer->writeData(priv->data.get(), length);
/// We are done
- (*callback_)(SUCCESS);
+ (*priv->callback)(SUCCESS);
}
}
More information about the bind10-changes
mailing list