[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