[Xorp-hackers] [PATCH 1/3] Supporting asynchronous server implementations - compiled.

ss at comp.lancs.ac.uk ss at comp.lancs.ac.uk
Tue Mar 8 05:27:06 PST 2011


From: Steven Simpson <ss at comp.lancs.ac.uk>

---
 xorp/libxipc/finder_client.cc            |   23 +++--
 xorp/libxipc/finder_client.hh            |   13 ++-
 xorp/libxipc/finder_client_xrl_target.cc |   35 +++++-
 xorp/libxipc/finder_client_xrl_target.hh |   12 ++-
 xorp/libxipc/finder_messenger.cc         |   14 ++-
 xorp/libxipc/finder_messenger.hh         |    5 +
 xorp/libxipc/xrl_cmd_map.cc              |    2 +-
 xorp/libxipc/xrl_cmd_map.hh              |   14 ++-
 xorp/libxipc/xrl_dispatcher.cc           |   26 ++++--
 xorp/libxipc/xrl_dispatcher.hh           |   20 +++-
 xorp/libxipc/xrl_error.hh                |    3 +
 xorp/libxipc/xrl_pf_stcp.cc              |   55 +++++++---
 xorp/libxipc/xrl_router.cc               |   11 +-
 xorp/libxipc/xrl_router.hh               |    8 +-
 xorp/xrl/scripts/tgt-gen                 |  171 ++++++++++++++++++++---------
 15 files changed, 297 insertions(+), 115 deletions(-)

diff --git a/xorp/libxipc/finder_client.cc b/xorp/libxipc/finder_client.cc
index 2fe7876..5713e5c 100644
--- a/xorp/libxipc/finder_client.cc
+++ b/xorp/libxipc/finder_client.cc
@@ -961,8 +961,16 @@ FinderClient::uncache_xrls_from_target(const string& target)
 			XORP_UINT_CAST(n), target.c_str());
 }
 
-XrlCmdError
-FinderClient::dispatch_tunneled_xrl(const string& xrl_str)
+void
+FinderClient::dispatch_tunneled_xrl_cb(const XrlError &e, const XrlArgs &a,
+				       XrlRespCallback cb) const
+{
+    cb->dispatch(XrlCmdError(e), a);
+}
+
+void
+FinderClient::dispatch_tunneled_xrl(const string& xrl_str,
+				    const XrlRespCallback& cb)
 {
     finder_trace_init("dispatch_tunneled_xrl(\"%s\")", xrl_str.c_str());
     Xrl xrl;
@@ -971,16 +979,17 @@ FinderClient::dispatch_tunneled_xrl(const string& xrl_str)
 	InstanceList::iterator i = find_instance(xrl.target());
 	if (i == _ids.end()) {
 	    finder_trace_result("target not found");
-	    return XrlCmdError::COMMAND_FAILED("target not found");
+	    cb->dispatch(XrlCmdError::COMMAND_FAILED("target not found"),
+			 XrlArgs());
 	}
 
 	XrlArgs ret_vals;
-	i->dispatcher()->dispatch_xrl(xrl.command(),
-				      xrl.args(), ret_vals);
+	XrlDispatcherCallback mycb =
+	    callback(this, &FinderClient::dispatch_tunneled_xrl_cb, cb);
+	i->dispatcher()->dispatch_xrl(xrl.command(), xrl.args(), mycb);
 	finder_trace_result("success");
-	return XrlCmdError::OKAY();
     } catch (InvalidString&) {
-	return XrlCmdError::COMMAND_FAILED("Bad Xrl string");
+	cb->dispatch(XrlCmdError::COMMAND_FAILED("Bad Xrl string"), XrlArgs());
     }
 }
 
diff --git a/xorp/libxipc/finder_client.hh b/xorp/libxipc/finder_client.hh
index 21e1f11..2d585ad 100644
--- a/xorp/libxipc/finder_client.hh
+++ b/xorp/libxipc/finder_client.hh
@@ -32,6 +32,8 @@
 #include "finder_messenger.hh"
 
 #include "xrl_pf.hh"
+#include "xrl_dispatcher.hh"
+#include "xrl_cmd_map.hh"
 
 class FinderClientOp;
 class FinderClientObserver;
@@ -76,7 +78,8 @@ public:
     virtual ~FinderClientXrlCommandInterface() {}
     virtual void uncache_xrl(const string& xrl) = 0;
     virtual void uncache_xrls_from_target(const string& target) = 0;
-    virtual XrlCmdError dispatch_tunneled_xrl(const string& xrl) = 0;
+    virtual void dispatch_tunneled_xrl(const string& xrl,
+				       const XrlRespCallback& cb) = 0;
 };
 
 /**
@@ -312,7 +315,13 @@ protected:
     // FinderClientXrlCommandInterface
     void uncache_xrl(const string& xrl);
     void uncache_xrls_from_target(const string& target);
-    XrlCmdError dispatch_tunneled_xrl(const string& xrl);
+    void dispatch_tunneled_xrl(const string& xrl_str,
+			       const XrlRespCallback& cb);
+
+private:
+    void
+    dispatch_tunneled_xrl_cb(const XrlError &e, const XrlArgs &a,
+			     XrlRespCallback cb) const;
 
 protected:
     void crank();
diff --git a/xorp/libxipc/finder_client_xrl_target.cc b/xorp/libxipc/finder_client_xrl_target.cc
index ce1ca05..4e33b21 100644
--- a/xorp/libxipc/finder_client_xrl_target.cc
+++ b/xorp/libxipc/finder_client_xrl_target.cc
@@ -22,6 +22,7 @@
 
 
 #include "libxorp/status_codes.h"
+#include "libxorp/callback.hh"
 #include "finder_client_xrl_target.hh"
 #include "finder_client.hh"
 
@@ -85,15 +86,37 @@ FinderClientXrlTarget::finder_client_0_2_remove_xrls_for_target_from_cache(
     return XrlCmdError::OKAY();
 }
 
+
+void
+FinderClientXrlTarget::async_finder_client_0_2_dispatch_tunneled_xrl
+(const string&	xrl,
+ FinderClient02DispatchTunneledXrlCB cb)
+{
+    _client->dispatch_tunneled_xrl
+	(xrl,
+	 callback(this,
+		  &FinderClientXrlTarget::dispatch_tunneled_xrl_cb,
+		  cb));
+}
+
+void
+FinderClientXrlTarget::dispatch_tunneled_xrl_cb
+(const XrlCmdError &e,
+ const XrlArgs &out,
+ FinderClient02DispatchTunneledXrlCB cb) const
+{
+    UNUSED(out);
+    cb->dispatch(XrlCmdError::OKAY(), e.error_code(), e.note());
+}
+
 XrlCmdError
 FinderClientXrlTarget::finder_client_0_2_dispatch_tunneled_xrl(
 						const string& xrl,
 						uint32_t&     xrl_errno,
-						string&	      xrl_errtxt
-						)
+						string&	      xrl_errtxt)
 {
-    XrlCmdError e = _client->dispatch_tunneled_xrl(xrl);
-    xrl_errno  = e.error_code();
-    xrl_errtxt = e.note();
-    return XrlCmdError::OKAY();
+    UNUSED(xrl);
+    UNUSED(xrl_errno);
+    UNUSED(xrl_errtxt);
+    return XrlCmdError::COMMAND_FAILED("Unreachable");
 }
diff --git a/xorp/libxipc/finder_client_xrl_target.hh b/xorp/libxipc/finder_client_xrl_target.hh
index 59cc2b0..b6c4e53 100644
--- a/xorp/libxipc/finder_client_xrl_target.hh
+++ b/xorp/libxipc/finder_client_xrl_target.hh
@@ -25,6 +25,7 @@
 #define __LIBXIPC_FINDER_CLIENT_XRL_TARGET_HH__
 
 #include "xrl/targets/finder_client_base.hh"
+#include "xrl_dispatcher.hh"
 
 class FinderClientXrlCommandInterface; 
 
@@ -46,12 +47,21 @@ public:
     XrlCmdError finder_client_0_2_remove_xrls_for_target_from_cache(
 							const string& target);
 
+    void async_finder_client_0_2_dispatch_tunneled_xrl
+    (const string&	xrl,
+     FinderClient02DispatchTunneledXrlCB);
     XrlCmdError finder_client_0_2_dispatch_tunneled_xrl(const string& xrl,
 							uint32_t& xrl_errno,
 							string&   xrl_errtxt);
-    
+
 protected:
     FinderClientXrlCommandInterface* _client;
+
+private:
+    void dispatch_tunneled_xrl_cb
+    (const XrlCmdError &e,
+     const XrlArgs &out,
+     FinderClient02DispatchTunneledXrlCB cb) const;
 };
 
 #endif // __LIBXIPC_FINDER_CLIENT_XRL_TARGET_HH__
diff --git a/xorp/libxipc/finder_messenger.cc b/xorp/libxipc/finder_messenger.cc
index 5e71386..74a5826 100644
--- a/xorp/libxipc/finder_messenger.cc
+++ b/xorp/libxipc/finder_messenger.cc
@@ -97,14 +97,24 @@ FinderMessengerBase::dispatch_xrl(uint32_t seqno, const Xrl& xrl)
     if (manager())
 	manager()->messenger_active_event(this);
     
-    XrlArgs reply_args;
-    XrlError e = ce->dispatch(xrl.args(), &reply_args);
+    ce->dispatch(xrl.args(),
+		 callback(this, &FinderMessengerBase::dispatch_xrl_cb, seqno));
+}
+
+void
+FinderMessengerBase::dispatch_xrl_cb(const XrlCmdError &e,
+				     const XrlArgs &reply_args,
+				     uint32_t seqno)
+{
     if (XrlCmdError::OKAY() == e) {
 	reply(seqno, e, &reply_args);
     } else {
 	reply(seqno, e, 0);
     }
 
+    // TODO: Is there any context that must be passed to the
+    // FinderMessengerManager, now that the events are asynchronous?
+
     // Announce we've dispatched xrl
     if (manager())
 	manager()->messenger_inactive_event(this);
diff --git a/xorp/libxipc/finder_messenger.hh b/xorp/libxipc/finder_messenger.hh
index d80405d..679bcf3 100644
--- a/xorp/libxipc/finder_messenger.hh
+++ b/xorp/libxipc/finder_messenger.hh
@@ -123,6 +123,11 @@ protected:
     void response_timeout(uint32_t seqno);
 
 private:
+    void
+    dispatch_xrl_cb(const XrlCmdError &e,
+		    const XrlArgs &reply_args,
+		    uint32_t seqno);
+
     class ResponseState {
     public:
 	ResponseState(uint32_t		   seqno,
diff --git a/xorp/libxipc/xrl_cmd_map.cc b/xorp/libxipc/xrl_cmd_map.cc
index 487f68e..0d25952 100644
--- a/xorp/libxipc/xrl_cmd_map.cc
+++ b/xorp/libxipc/xrl_cmd_map.cc
@@ -42,7 +42,7 @@ XrlCmdMap::add_handler(const XrlCmdEntry& cmd)
 }
 
 bool
-XrlCmdMap::add_handler(const string& cmd, const XrlRecvCallback& rcb)
+XrlCmdMap::add_handler(const string& cmd, XrlRecvCallback rcb)
 {
     return add_handler(XrlCmdEntry(cmd, rcb));
 }
diff --git a/xorp/libxipc/xrl_cmd_map.hh b/xorp/libxipc/xrl_cmd_map.hh
index 45c6bd6..da8f522 100644
--- a/xorp/libxipc/xrl_cmd_map.hh
+++ b/xorp/libxipc/xrl_cmd_map.hh
@@ -33,7 +33,13 @@
 #include "xrl_error.hh"
 
 typedef
-XorpCallback2<const XrlCmdError, const XrlArgs&, XrlArgs*>::RefPtr XrlRecvCallback;
+XorpCallback2<void, const XrlCmdError &, const XrlArgs &>::RefPtr
+XrlRespCallback;
+
+typedef
+XorpCallback2<void, const XrlArgs&, XrlRespCallback>::RefPtr XrlRecvCallback;
+
+
 
 class XrlCmdEntry {
 public:
@@ -45,8 +51,8 @@ public:
 
     const string& name() const { return _name; }
 
-    const XrlCmdError dispatch(const XrlArgs& inputs, XrlArgs* outputs) const {
-	return _cb->dispatch(inputs, outputs);
+    void dispatch(const XrlArgs& inputs, XrlRespCallback resp) const {
+	_cb->dispatch(inputs, resp);
     }
 
 protected:
@@ -65,7 +71,7 @@ public:
 
     const string& name() const { return _name; }
 
-    virtual bool add_handler(const string& cmd, const XrlRecvCallback& rcb);
+    virtual bool add_handler(const string& cmd, XrlRecvCallback rcb);
 
     virtual bool remove_handler (const string& name);
 
diff --git a/xorp/libxipc/xrl_dispatcher.cc b/xorp/libxipc/xrl_dispatcher.cc
index ead5e09..04b618f 100644
--- a/xorp/libxipc/xrl_dispatcher.cc
+++ b/xorp/libxipc/xrl_dispatcher.cc
@@ -51,20 +51,22 @@ do {									      \
 // ----------------------------------------------------------------------------
 // XrlDispatcher methods
 
-XrlError
+void
 XrlDispatcher::dispatch_xrl(const string&  method_name,
 			    const XrlArgs& inputs,
-			    XrlArgs&       outputs) const
+			    XrlDispatcherCallback resp) const
 {
     const XrlCmdEntry* c = get_handler(method_name.c_str());
     if (c == 0) {
 	trace_xrl_dispatch("dispatch_xrl (invalid) ", method_name);
 	debug_msg("No handler for %s\n", method_name.c_str());
-	return XrlError::NO_SUCH_METHOD();
+	resp->dispatch(XrlError::NO_SUCH_METHOD(), XrlArgs());
+	return;
     }
 
     trace_xrl_dispatch("dispatch_xrl (valid) ", method_name);
-    return c->dispatch(inputs, &outputs);
+    c->dispatch(inputs,
+		callback(this, &XrlDispatcher::dispatch_cb, resp));
 }
 
 XrlDispatcher::XI*
@@ -77,8 +79,18 @@ XrlDispatcher::lookup_xrl(const string& name) const
     return new XI(c);
 }
 
-XrlError
-XrlDispatcher::dispatch_xrl_fast(const XI& xi, XrlArgs& outputs) const
+void
+XrlDispatcher::dispatch_xrl_fast(const XI& xi,
+				 XrlDispatcherCallback resp) const
 {
-    return xi._cmd->dispatch(xi._xrl.args(), &outputs);
+    xi._cmd->dispatch(xi._xrl.args(),
+		      callback(this, &XrlDispatcher::dispatch_cb, resp));
+}
+
+void
+XrlDispatcher::dispatch_cb(const XrlCmdError &err,
+			   const XrlArgs &outputs,
+			   XrlDispatcherCallback resp) const
+{
+    resp->dispatch(err, outputs);
 }
diff --git a/xorp/libxipc/xrl_dispatcher.hh b/xorp/libxipc/xrl_dispatcher.hh
index 6dadb8b..43fb12d 100644
--- a/xorp/libxipc/xrl_dispatcher.hh
+++ b/xorp/libxipc/xrl_dispatcher.hh
@@ -25,6 +25,11 @@
 
 #include "xrl_cmd_map.hh"
 
+typedef
+XorpCallback2<void, const XrlError &, const XrlArgs &>::RefPtr
+XrlDispatcherCallback;
+
+
 class XrlDispatcher : public XrlCmdMap {
 public:
     struct XI {
@@ -40,11 +45,16 @@ public:
     {}
     virtual ~XrlDispatcher() {}
 
-    virtual XI*	       lookup_xrl(const string& name) const;
-    virtual XrlError   dispatch_xrl(const string& method_name,
-				    const XrlArgs& in,
-				    XrlArgs& out) const;
-    XrlError	       dispatch_xrl_fast(const XI& xi, XrlArgs& out) const;
+    virtual XI*	 lookup_xrl(const string& name) const;
+    virtual void dispatch_xrl(const string& method_name,
+			      const XrlArgs& in,
+			      XrlDispatcherCallback resp) const;
+    void	 dispatch_xrl_fast(const XI& xi,
+				   XrlDispatcherCallback resp) const;
+
+private:
+    void dispatch_cb(const XrlCmdError &, const XrlArgs &,
+		     XrlDispatcherCallback resp) const;
 };
 
 #endif // __LIBXIPC_XRL_DISPATCHER_HH__
diff --git a/xorp/libxipc/xrl_error.hh b/xorp/libxipc/xrl_error.hh
index 7ae7eed..6909a96 100644
--- a/xorp/libxipc/xrl_error.hh
+++ b/xorp/libxipc/xrl_error.hh
@@ -163,6 +163,7 @@ protected:
     string	     _note;
 };
 
+class FinderClient;
 
 /**
  * Error codes for user callbacks.
@@ -221,6 +222,8 @@ private:
     XrlCmdError(const XrlError& xe) : _xrl_error(xe) {}
     XrlError _xrl_error;
     static XrlCmdError _xce_ok;
+
+    friend class FinderClient;
 };
 
 
diff --git a/xorp/libxipc/xrl_pf_stcp.cc b/xorp/libxipc/xrl_pf_stcp.cc
index e441809..a1b6c58 100644
--- a/xorp/libxipc/xrl_pf_stcp.cc
+++ b/xorp/libxipc/xrl_pf_stcp.cc
@@ -130,6 +130,9 @@ public:
 
     void dispatch_request(uint32_t seqno, bool batch, const uint8_t* buffer,
 			  size_t bytes);
+    void transmit_response(const XrlError &e, const XrlArgs &response,
+			   uint32_t seqno, bool batch);
+
     void ack_helo(uint32_t seqno);
 
     void read_event(BufferedAsyncReader* 	reader,
@@ -151,8 +154,8 @@ public:
     string toString() const;
 
 private:
-    XrlError do_dispatch(const uint8_t* packed_xrl, size_t packed_xrl_bytes,
-                         XrlArgs& response);
+    void do_dispatch(const uint8_t* packed_xrl, size_t packed_xrl_bytes,
+		     XrlDispatcherCallback cb);
 
     XrlPFSTCPListener& _parent;
     XorpFd _sock;
@@ -251,10 +254,10 @@ STCPRequestHandler::read_event(BufferedAsyncReader*		/* source */,
     _reader.set_trigger_bytes(STCPPacketHeader::header_size());
 }
 
-XrlError
+void
 STCPRequestHandler::do_dispatch(const uint8_t* packed_xrl,
 			        size_t packed_xrl_bytes,
-			        XrlArgs& response)
+				XrlDispatcherCallback cb)
 {
     static XrlError e(XrlError::INTERNAL_ERROR().error_code(), "corrupt xrl");
 
@@ -263,33 +266,44 @@ STCPRequestHandler::do_dispatch(const uint8_t* packed_xrl,
 
     string command;
     size_t cmdsz = Xrl::unpack_command(command, packed_xrl, packed_xrl_bytes);
-    if (!cmdsz)
-	return e;
+    if (!cmdsz) {
+	cb->dispatch(e, XrlArgs());
+	return;
+    }
 
     XrlDispatcher::XI* xi = d->lookup_xrl(command);
-    if (!xi)
-	return e;
+    if (!xi) {
+	cb->dispatch(e, XrlArgs());
+	return;
+    }
 
     Xrl& xrl = xi->_xrl;
 
     try {
 	if (xi->_new) {
-	    if (xrl.unpack(packed_xrl, packed_xrl_bytes) != packed_xrl_bytes)
-		return e;
+	    if (xrl.unpack(packed_xrl, packed_xrl_bytes) != packed_xrl_bytes) {
+		cb->dispatch(e, XrlArgs());
+		return;
+	    }
+
 
 	    xi->_new = false;
 	} else {
 	    packed_xrl       += cmdsz;
 	    packed_xrl_bytes -= cmdsz;
 
-	    if (xrl.fill(packed_xrl, packed_xrl_bytes) != packed_xrl_bytes)
-		return e;
+	    if (xrl.fill(packed_xrl, packed_xrl_bytes) != packed_xrl_bytes) {
+		cb->dispatch(e, XrlArgs());
+		return;
+	    }
+
 	}
     } catch (...) {
-	return e;
+	cb->dispatch(e, XrlArgs());
+	return;
     }
 
-    return d->dispatch_xrl_fast(*xi, response);
+    return d->dispatch_xrl_fast(*xi, cb);
 }
 
 void
@@ -298,11 +312,16 @@ STCPRequestHandler::dispatch_request(uint32_t 		seqno,
 				     const uint8_t* 	packed_xrl,
 				     size_t 		packed_xrl_bytes)
 {
-    XrlArgs response;
-    XrlError e;
-
-    e = do_dispatch(packed_xrl, packed_xrl_bytes, response);
+    do_dispatch(packed_xrl, packed_xrl_bytes,
+		callback(this, &STCPRequestHandler::transmit_response,
+			 seqno, batch));
+}
 
+void STCPRequestHandler::transmit_response(const XrlError &e,
+					   const XrlArgs &response,
+					   uint32_t seqno,
+					   bool batch)
+{
     size_t xrl_response_bytes = response.packed_bytes();
     size_t note_bytes = e.note().size();
 
diff --git a/xorp/libxipc/xrl_router.cc b/xorp/libxipc/xrl_router.cc
index e547cbf..d46f8a9 100644
--- a/xorp/libxipc/xrl_router.cc
+++ b/xorp/libxipc/xrl_router.cc
@@ -372,7 +372,7 @@ XrlRouter::finalize()
 }
 
 bool
-XrlRouter::add_handler(const string& cmd, const XrlRecvCallback& rcb)
+XrlRouter::add_handler(const string& cmd, XrlRecvCallback rcb)
 {
     if (finalized()) {
 	XLOG_ERROR("Attempting to add handler after XrlRouter finalized.  Handler = \"%s\"", cmd.c_str());
@@ -650,17 +650,18 @@ XrlRouter::send(const Xrl& xrl, const XrlCallback& user_cb)
     return true;
 }
 
-XrlError
+void
 XrlRouter::dispatch_xrl(const string&	method_name,
 			const XrlArgs&	inputs,
-			XrlArgs&	outputs) const
+			XrlDispatcherCallback resp) const
 {
     string resolved_method;
     if (_fc->query_self(method_name, resolved_method) == true) {
-	return XrlDispatcher::dispatch_xrl(resolved_method, inputs, outputs);
+	XrlDispatcher::dispatch_xrl(resolved_method, inputs, resp);
+	return;
     }
     debug_msg("Could not find mapping for %s\n", method_name.c_str());
-    return XrlError::NO_SUCH_METHOD();
+    resp->dispatch(XrlError::NO_SUCH_METHOD(), XrlArgs());
 }
 
 XrlDispatcher::XI*
diff --git a/xorp/libxipc/xrl_router.hh b/xorp/libxipc/xrl_router.hh
index 9478f44..700152a 100644
--- a/xorp/libxipc/xrl_router.hh
+++ b/xorp/libxipc/xrl_router.hh
@@ -130,7 +130,7 @@ public:
      * @param rcb callback to be dispatched when XRL method is received for
      * invocation.
      */
-    bool add_handler(const string& cmd, const XrlRecvCallback& rcb);
+    bool add_handler(const string& cmd, XrlRecvCallback rcb);
 
     /**
      * @return EventLoop used by XrlRouter instance.
@@ -176,9 +176,9 @@ protected:
      */
     virtual void finder_ready_event(const string& tgt_name);
 
-    XrlError dispatch_xrl(const string&	 method_name,
-			  const XrlArgs& inputs,
-			  XrlArgs&	 outputs) const;
+    void dispatch_xrl(const string&	 method_name,
+		      const XrlArgs& inputs,
+		      XrlDispatcherCallback resp) const;
 
     /**
      * Resolve callback (slow path).
diff --git a/xorp/xrl/scripts/tgt-gen b/xorp/xrl/scripts/tgt-gen
index 899cf13..3ce47e0 100755
--- a/xorp/xrl/scripts/tgt-gen
+++ b/xorp/xrl/scripts/tgt-gen
@@ -9,7 +9,7 @@ import os, sys
 import Xif.util
 
 from Xif.util import \
-     joining_csv, csv, cpp_name, cpp_classname, xorp_indent_string, xorp_indent
+     joining_csv, csv, cpp_name, caps_cpp_classname, cpp_classname, xorp_indent_string, xorp_indent
 
 from Xif.xiftypes import \
      XrlArg, XrlMethod, XrlInterface, XrlTarget
@@ -69,7 +69,7 @@ def target_declare_handler_table(cls):
     s = """
     struct handler_table {
         const char *name;
-        const XrlCmdError (%s::*method)(const XrlArgs&, XrlArgs*);
+        void (%s::*method)(const XrlArgs&, XrlRespCallback);
     };
 
     static const struct handler_table handlers[];
@@ -100,6 +100,7 @@ def target_virtual_fns(methods):
                                  "Pure-virtual function that needs to be implemented to:")
         if len(kdoc_note):
             r += kdoc_note + "\n"
+
         r += "    virtual XrlCmdError %s("% cpp_name(x.name())
 
         # input args
@@ -109,7 +110,7 @@ def target_virtual_fns(methods):
 
         for a in x.args():
             cpa = "\n%sconst %s&\t%s" % \
-                  (xorp_indent(2), a.cpp_type(), cpp_name(a.name()))
+                (xorp_indent(2), a.cpp_type(), cpp_name(a.name()))
             args.append(cpa)
 
         # output args
@@ -124,13 +125,41 @@ def target_virtual_fns(methods):
         r += csv(args)
 
         r += ") = 0;\n\n"
+
+
+
+        r += "    typedef\n"
+        r += "    XorpCallback%s<void, const XrlCmdError &" % (len(x.rargs()) + 1)
+        for a in x.rargs():
+            r += ",\n%sconst %s&" % (xorp_indent(2), a.cpp_type())
+        r += ">::RefPtr\n    %sCB;\n" % (caps_cpp_classname(x.name()))
+
+
+
+        r += "    virtual void async_%s\n       (" \
+            % cpp_name(x.name())
+
+        # input args
+        for a in x.args():
+            r += "\n%sconst %s&\t%s," % \
+                  (xorp_indent(2), a.cpp_type(), cpp_name(a.name()))
+
+        r += "\n%s%sCB);\n\n" % \
+            (xorp_indent(2), caps_cpp_classname(x.name()))
     return r
 
 def target_declare_handlers(methods):
     s = ""
     for x in methods:
-        s += "    const XrlCmdError handle_%s(const XrlArgs& in, XrlArgs* out);\n\n" \
-             % cpp_name(x.name())
+        s += "    void handle_%s\n       " % cpp_name(x.name()) + \
+            "(const XrlArgs& in, XrlRespCallback);\n"
+
+        s += "    void callback_%s\n       (const XrlCmdError &e" \
+            % cpp_name(x.name())
+        for a in x.rargs():
+            s += ",\n%sconst %s& arg_%s" \
+                % (xorp_indent(2), a.cpp_type(), cpp_name(a.name()))
+        s += ",\n        XrlRespCallback);\n\n"
     return s;
 
 def target_declare_handler_hooks():
@@ -159,74 +188,110 @@ def target_handler_hooks(cls, name):
 def target_handler_methods(cls, name, methods):
     s = ""
     for m in methods:
-        s += "const XrlCmdError\n"
-        if len(m.rargs()):
-            argarg = "pxa_outputs"
-        else:
-            argarg = "/* pxa_outputs */"
-        s += "%s::handle_%s(const XrlArgs& xa_inputs, XrlArgs* %s)\n" % \
-             (cls, cpp_name(m.name()), argarg)
+
+
+
+
+        s += "\nvoid\n"
+        s += "%s::callback_%s\n    (const XrlCmdError &e" \
+            % (cls, cpp_name(m.name()))
+        for r in m.rargs():
+            s += ",\n     "
+            s += "const %s& rarg_%s" % (r.cpp_type(), cpp_name(r.name()))
+        s += ",\n     XrlRespCallback c_b)\n"
+        s += "{\n"
+
+        s += xorp_indent(1) + "XrlArgs out;\n"
+        s += \
+"""    if (e != XrlCmdError::OKAY()) {
+	XLOG_WARNING(\"Handling method for %%s failed: %%s\",
+		     \"%s\", e.str().c_str());
+    } else {
+""" % m.name()
+
+        if m.rargs():
+            s += "\n        /* Marshall return values */\n        try {\n"
+            for r in m.rargs():
+                s += xorp_indent(3) + "out.add(\"%s\", rarg_%s);\n" % \
+                    (r.name(), cpp_name(r.name()))
+            s += \
+"""        } catch (const XrlArgs::XrlAtomFound& ) {
+	    XLOG_FATAL("Duplicate atom name"); /* XXX Should never happen */
+        }
+
+"""
+
+        s += "        c_b->dispatch(e, out);\n    }\n}\n\n"
+
+
+        s += "\nvoid\n"
+        s += "%s::handle_%s(const XrlArgs& xa_inputs, XrlRespCallback c_b)\n" % \
+             (cls, cpp_name(m.name()))
         s += "{"
         s += """
     if (xa_inputs.size() != %d) {
 	XLOG_ERROR(\"Wrong number of arguments (%%u != %%u) handling %%s\",
             XORP_UINT_CAST(%d), XORP_UINT_CAST(xa_inputs.size()), \"%s\");
-	return XrlCmdError::BAD_ARGS();
+	c_b->dispatch(XrlCmdError::BAD_ARGS(), XrlArgs());
+        return;
     }
 """ % (len(m.args()), len(m.args()), m.name())
 
-        if len(m.rargs()):
-            s += """
-    if (pxa_outputs == 0) {
-	XLOG_FATAL(\"Return list empty\");
-	return XrlCmdError::BAD_ARGS();
-    }
-"""
-    	s += "\n    /* Return value declarations */\n"
-    	for r in m.rargs():
-            s += "    %s %s;\n" % (r.cpp_type(), cpp_name(r.name()))
 
         s += xorp_indent(1) + "try {\n"
-        s += xorp_indent(2) + "XrlCmdError e = %s(" % cpp_name(m.name())
-        get_reqs = []
+        s += xorp_indent(2) + \
+            "%sCB mycb =\n%s callback(this, &%s::callback_%s, c_b);\n" \
+            % (caps_cpp_classname(m.name()), xorp_indent(3), \
+                   cls, cpp_name(m.name()))
+        s += xorp_indent(2) + "async_%s(" % cpp_name(m.name())
 	i = 0
         for a in m.args():
-            get_reqs.append("\n" + xorp_indent(3) + \
-                            "xa_inputs.get(%d, \"%s\").%s()" \
-                            % (i, a.name(), a.accessor()))
-	    i += 1
-        ret_vals = []
-        for r in m.rargs():
-            ret_vals.append("\n" + xorp_indent(3) + "%s" % cpp_name(r.name()))
-        s += csv(get_reqs + ret_vals, ",") + ");\n"
-
-        s += \
-"""	if (e != XrlCmdError::OKAY()) {
-	    XLOG_WARNING(\"Handling method for %%s failed: %%s\",
-            		 \"%s\", e.str().c_str());
-	    return e;
-        }
-""" % m.name()
+            s += "\n" + xorp_indent(3) + \
+               "xa_inputs.get(%d, \"%s\").%s()," \
+                % (i, a.name(), a.accessor())
+            i += 1
+        s += " mycb);\n"
 
     	s += \
 """    } catch (const XrlArgs::BadArgs& e) {
 	XLOG_ERROR(\"Error decoding the arguments: %s\", e.str().c_str());
-	return XrlCmdError::BAD_ARGS(e.str());
+	c_b->dispatch(XrlCmdError::BAD_ARGS(e.str()), XrlArgs());
+        return;
     }
 """
+        s += "}\n"
 
-        if m.rargs():
-            s += "\n    /* Marshall return values */\n    try {\n"
-            for r in m.rargs():
-                s += xorp_indent(2) + "%s->add(\"%s\", %s);\n" % \
-                     (argarg, r.name(), cpp_name(r.name()))
-            s += \
-"""    } catch (const XrlArgs::XrlAtomFound& ) {
-	XLOG_FATAL("Duplicate atom name"); /* XXX Should never happen */
-    }
-"""
+        s += "\nvoid\n%s::async_%s(" \
+            % (cls, cpp_name(m.name()))
+
+        # input args
+        for a in m.args():
+            s += "\n%sconst %s&\targ_%s," % \
+                (xorp_indent(2), a.cpp_type(), cpp_name(a.name()))
+
+        s += "\n%s%sCB c_b)\n{\n" % \
+            (xorp_indent(2), caps_cpp_classname(m.name()))
+
+    	s += "\n    /* Return value declarations */\n"
+    	for r in m.rargs():
+            s += "    %s rarg_%s;\n" % (r.cpp_type(), cpp_name(r.name()))
+
+        s += "    XrlCmdError e = %s(" % cpp_name(m.name())
+        sep = ""
+    	for r in m.args():
+            s += "%s\n        arg_%s" % (sep, cpp_name(r.name()))
+            sep = ","
+        for r in m.rargs():
+            s += "%s\n        rarg_%s" % (sep, cpp_name(r.name()))
+            sep = ","
+        s += ");\n"
+        s += "    c_b->dispatch(e"
+    	for r in m.rargs():
+            s += ",\n        rarg_%s" % (cpp_name(r.name()))
+            sep = ","
+        s += ");\n"
+        s += "}\n"
 
-        s += "    return XrlCmdError::OKAY();\n}\n\n"
     return s
 
 def protect(file):
-- 
1.7.0.4



More information about the Xorp-hackers mailing list