X-Git-Url: http://xvm.mit.edu/gitweb/invirt/third/libt4.git/blobdiff_plain/f2170465073de34adf89161d4287182b518352c4..2546a41ad36fdc9ef6471cb35a1d56930ae1b527:/rpc/marshall.h diff --git a/rpc/marshall.h b/rpc/marshall.h index 676a682..abeaae7 100644 --- a/rpc/marshall.h +++ b/rpc/marshall.h @@ -12,11 +12,14 @@ #include #include "lang/verify.h" +using proc_t = uint32_t; +using status_t = int32_t; + struct request_header { - request_header(int x=0, int p=0, unsigned c=0, unsigned s=0, int xi=0) : + request_header(int x=0, proc_t p=0, unsigned c=0, unsigned s=0, int xi=0) : xid(x), proc(p), clt_nonce(c), srv_nonce(s), xid_rep(xi) {} int xid; - int proc; + proc_t proc; unsigned int clt_nonce; unsigned int srv_nonce; int xid_rep; @@ -134,7 +137,14 @@ marshall& operator<<(marshall &, int16_t); marshall& operator<<(marshall &, uint64_t); marshall& operator<<(marshall &, const std::string &); -template marshall & +template +struct is_enumerable : std::false_type {}; + +template struct is_enumerable().cbegin(), std::declval().cend(), void()) +> : std::true_type {}; + +template typename std::enable_if::value, marshall>::type & operator<<(marshall &m, const A &x) { m << (unsigned int) x.size(); for (const auto &a : x) @@ -144,9 +154,17 @@ operator<<(marshall &m, const A &x) { template marshall & operator<<(marshall &m, const std::pair &d) { - m << d.first; - m << d.second; - return m; + return m << d.first << d.second; +} + +template +using enum_type_t = typename std::enable_if::value, typename std::underlying_type::type>::type; +template constexpr inline enum_type_t from_enum(E e) noexcept { return (enum_type_t)e; } +template constexpr inline E to_enum(enum_type_t value) noexcept { return (E)value; } + +template typename std::enable_if::value, marshall>::type & +operator<<(marshall &m, E e) { + return m << from_enum(e); } class unmarshall; @@ -162,6 +180,8 @@ unmarshall& operator>>(unmarshall &, size_t &); unmarshall& operator>>(unmarshall &, uint64_t &); unmarshall& operator>>(unmarshall &, int64_t &); unmarshall& operator>>(unmarshall &, std::string &); +template typename std::enable_if::value, unmarshall>::type & +operator>>(unmarshall &u, E &e); class unmarshall { private: @@ -235,7 +255,8 @@ class unmarshall { } }; -template unmarshall & operator>>(unmarshall &u, A &x) { +template typename std::enable_if::value, unmarshall>::type & +operator>>(unmarshall &u, A &x) { unsigned n = u.grab(); x.clear(); while (n--) @@ -257,6 +278,12 @@ operator>>(unmarshall &u, std::pair &d) { return u >> d.first >> d.second; } +template typename std::enable_if::value, unmarshall>::type & +operator>>(unmarshall &u, E &e) { + e = to_enum(u.grab>()); + return u; +} + typedef std::function handler; // @@ -311,17 +338,17 @@ struct VerifyOnFailure { // One for function pointers... -template -typename std::enable_if::value, int>::type -invoke(F f, void *, R & r, args_type & t, tuple_indices) { +template +typename std::enable_if::value, RV>::type +invoke(RV, F f, void *, R & r, args_type & t, tuple_indices) { return f(r, std::move(std::get(t))...); } // And one for pointers to member functions... -template -typename std::enable_if::value, int>::type -invoke(F f, C *c, R & r, args_type & t, tuple_indices) { +template +typename std::enable_if::value, RV>::type +invoke(RV, F f, C *c, R & r, args_type & t, tuple_indices) { return (c->*f)(r, std::move(std::get(t))...); } @@ -339,8 +366,8 @@ template -struct marshalled_func_imp { +template +struct marshalled_func_imp { static inline handler *wrap(F f, C *c=nullptr) { // This type definition corresponds to an empty struct with // template parameters running from 0 up to (# args) - 1. @@ -351,20 +378,20 @@ struct marshalled_func_imp { using ArgsStorage = std::tuple::type...>; // Allocate a handler (i.e. std::function) to hold the lambda // which will unmarshall RPCs and call f. - return new handler([=](unmarshall &u, marshall &m) -> int { + return new handler([=](unmarshall &u, marshall &m) -> RV { // Unmarshall each argument with the correct type and store the // result in a tuple. ArgsStorage t = {u.grab::type>()...}; // Verify successful unmarshalling of the entire input stream. if (!u.okdone()) - return ErrorHandler::unmarshall_args_failure(); + return (RV)ErrorHandler::unmarshall_args_failure(); // Allocate space for the RPC response -- will be passed into the // function as an lvalue reference. R r; // Perform the invocation. Note that Indices() calls the default // constructor of the empty struct with the special template // parameters. - int b = invoke(f, c, r, t, Indices()); + RV b = invoke(RV(), f, c, r, t, Indices()); // Marshall the response. m << r; // Make like a tree. @@ -381,13 +408,13 @@ struct marshalled_func_imp { template struct marshalled_func; -template -struct marshalled_func : - public marshalled_func_imp {}; +template +struct marshalled_func : + public marshalled_func_imp {}; -template -struct marshalled_func : - public marshalled_func_imp {}; +template +struct marshalled_func : + public marshalled_func_imp {}; template struct marshalled_func> :