BIND 10 track1914, updated. 4aea6b74d6a48ee9e3666745ed7da416b31c2728 [1914] Cleanup: constify

BIND 10 source code commits bind10-changes at lists.isc.org
Thu May 17 14:50:27 UTC 2012


The branch, track1914 has been updated
       via  4aea6b74d6a48ee9e3666745ed7da416b31c2728 (commit)
       via  d06b9b84af34e84cadab87920fc1742f8b029d7c (commit)
       via  132d530f80654677dfc10e9a0f88edd272666385 (commit)
      from  b174ac98fbe2c9bae96edd0faf2e8884cbbac4fd (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 4aea6b74d6a48ee9e3666745ed7da416b31c2728
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Thu May 17 16:49:47 2012 +0200

    [1914] Cleanup: constify
    
    The values inside the request never need to be changed after they are
    stored.

commit d06b9b84af34e84cadab87920fc1742f8b029d7c
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Thu May 17 16:46:27 2012 +0200

    [1914] Cleanup: remove shared_ptr
    
    It seems a list can be declared for a class that is not fully defined
    yet. So there's no need for pointers, so even less for shared ones.

commit 132d530f80654677dfc10e9a0f88edd272666385
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Thu May 17 16:43:21 2012 +0200

    [1914] Check for async requests on a new message
    
    We now check if the message looks like something a callback wants in the
    checkCommand() call. For some reason, it does not seem to work with the
    tests, it needs to be checked why.

-----------------------------------------------------------------------

Summary of changes:
 src/lib/config/ccsession.cc |   86 ++++++++++++++++++++++++++++++++++++++-----
 src/lib/config/ccsession.h  |   18 ++++++++-
 2 files changed, 92 insertions(+), 12 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/config/ccsession.cc b/src/lib/config/ccsession.cc
index 38474c8..bcabd39 100644
--- a/src/lib/config/ccsession.cc
+++ b/src/lib/config/ccsession.cc
@@ -601,6 +601,11 @@ ModuleCCSession::checkCommand() {
     ConstElementPtr cmd, routing, data;
     if (session_.group_recvmsg(routing, data, true)) {
 
+        // In case the message is wanted asynchronously, it gets used.
+        if (checkAsyncRecv(routing, data)) {
+            return (0);
+        }
+
         /* ignore result messages (in case we're out of sync, to prevent
          * pingpongs */
         if (data->getType() != Element::map || data->contains("result")) {
@@ -766,10 +771,17 @@ ModuleCCSession::sendStopping() {
 
 class ModuleCCSession::AsyncRecvRequest {
 public: // Everything is public here, as the definition is hidden anyway
-    AsyncRecvCallback callback;
-    string recipient;
-    int seq;
-    bool is_reply;
+    AsyncRecvRequest(const AsyncRecvCallback& cb, const string& rcp, int sq,
+                     bool reply) :
+        callback(cb),
+        recipient(rcp),
+        seq(sq),
+        is_reply(reply)
+    {}
+    const AsyncRecvCallback callback;
+    const string recipient;
+    const int seq;
+    const bool is_reply;
 };
 
 ModuleCCSession::AsyncRecvRequestID
@@ -777,13 +789,67 @@ ModuleCCSession::groupRecvMsgAsync(const AsyncRecvCallback& callback,
                                    bool is_reply, int seq,
                                    const string& recipient) {
     // This just stores the request, the handling is done in checkCommand()
-    boost::shared_ptr<AsyncRecvRequest> request(new AsyncRecvRequest);
-    request->callback = callback;
-    request->recipient = recipient;
-    request->seq = seq;
-    request->is_reply = is_reply;
+
     // push_back would be simpler, but it does not return the iterator we need
-    return (async_recv_requests_.insert(async_recv_requests_.end(), request));
+    return (async_recv_requests_.insert(async_recv_requests_.end(),
+                                        AsyncRecvRequest(callback, recipient,
+                                                         seq, is_reply)));
+}
+
+bool
+ModuleCCSession::checkAsyncRecv(const ConstElementPtr& envelope,
+                                const ConstElementPtr& msg)
+{
+    for (AsyncRecvRequestID request(async_recv_requests_.begin());
+         request != async_recv_requests_.end(); ++ request) {
+        // Just go through all the requests and look for a matching one
+        if (requestMatch(*request, envelope)) {
+            // We want the request to be still alive at the time we
+            // call the callback. But we need to remove it on an exception
+            // too, so we use the class. If just C++ had the finally keyword.
+            class RequestDeleter {
+            public:
+                RequestDeleter(AsyncRecvRequests& requests,
+                               AsyncRecvRequestID& request) :
+                    requests_(requests),
+                    request_(request)
+                { }
+                ~ RequestDeleter() {
+                    requests_.erase(request_);
+                }
+            private:
+                AsyncRecvRequests requests_;
+                AsyncRecvRequestID request_;
+            } deleter(async_recv_requests_, request);
+            // Call the callback
+            request->callback(envelope, msg, request);
+        }
+    }
+    return (false);
+}
+
+bool
+ModuleCCSession::requestMatch(const AsyncRecvRequest& request,
+                              const ConstElementPtr& envelope) const
+{
+    if (request.is_reply != envelope->contains("reply")) {
+        // Wrong type of message
+        return (false);
+    }
+    if (request.is_reply &&
+        (request.seq == -1 ||
+         request.seq == envelope->get("reply")->intValue())) {
+        // This is the correct reply
+        return (true);
+    }
+    if (!request.is_reply &&
+        (request.recipient == "" ||
+         request.recipient == envelope->get("group")->stringValue())) {
+        // This is the correct command
+        return (true);
+    }
+    // If nothing from the above, we don't want it
+    return (false);
 }
 
 }
diff --git a/src/lib/config/ccsession.h b/src/lib/config/ccsession.h
index 7d2bb71..25b65b7 100644
--- a/src/lib/config/ccsession.h
+++ b/src/lib/config/ccsession.h
@@ -369,10 +369,10 @@ public:
     class AsyncRecvRequest;
 
     /// \brief List of all requests for asynchronous reads.
-    typedef std::list<boost::shared_ptr<AsyncRecvRequest> > AsyncRecvRequests;
+    typedef std::list<AsyncRecvRequest> AsyncRecvRequests;
 
     /// \brief Identifier of single request for asynchronous read.
-    typedef AsyncRecvRequests::const_iterator AsyncRecvRequestID;
+    typedef AsyncRecvRequests::iterator AsyncRecvRequestID;
 
     /// \brief Callback which is called when an asynchronous receive finishes.
     ///
@@ -475,6 +475,20 @@ private:
     ModuleSpec readModuleSpecification(const std::string& filename);
     void startCheck();
     void sendStopping();
+    /// \brief Check if the message is wanted by asynchronous read
+    ///
+    /// It checks if any of the previously queued requests match
+    /// the message. If so, the callback is dispatched and removed.
+    ///
+    /// \param envelope The envelope of the message.
+    /// \param msg The actual message data.
+    /// \return True if the message was used for a callback, false
+    ///     otherwise.
+    bool checkAsyncRecv(const data::ConstElementPtr& envelope,
+                        const data::ConstElementPtr& msg);
+    /// \brief Checks if a message with this envelope matches the request
+    bool requestMatch(const AsyncRecvRequest& request,
+                      const data::ConstElementPtr& envelope) const;
 
     bool started_;
     std::string module_name_;



More information about the bind10-changes mailing list