[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