X-Git-Url: http://xvm.mit.edu/gitweb/invirt/third/libt4.git/blobdiff_plain/4a160f880ce46153acb23b137f30fd588df5fb9d..d54215aea2a7321ab0f2dc7b0042fea2b7ff5df5:/rpc/rpc.h diff --git a/rpc/rpc.h b/rpc/rpc.h index 84c12f3..7b65101 100644 --- a/rpc/rpc.h +++ b/rpc/rpc.h @@ -5,6 +5,7 @@ #include #include +#include "rpc_protocol.h" #include "thr_pool.h" #include "marshall.h" #include "marshall_wrap.h" @@ -15,23 +16,27 @@ namespace rpc { static constexpr milliseconds to_min{100}; } -class rpc_const { - public: - static const unsigned int bind = 1; // handler number reserved for bind - static const int timeout_failure = -1; - static const int unmarshal_args_failure = -2; - static const int unmarshal_reply_failure = -3; - static const int atmostonce_failure = -4; - static const int oldsrv_failure = -5; - static const int bind_failure = -6; - static const int cancel_failure = -7; -}; +template struct is_valid_call : false_type {}; + +template +struct is_valid_call : true_type {}; + +template struct is_valid_registration : false_type {}; + +template +struct is_valid_registration::type...), S(R &, Args...)> : true_type {}; + +template +struct is_valid_registration : is_valid_registration {}; // rpc client endpoint. // manages a xid space per destination socket // threaded: multiple threads can be sending RPCs, class rpcc : private connection_delegate { private: + using proc_id_t = rpc_protocol::proc_id_t; + template + using proc_t = rpc_protocol::proc_t; // manages per rpc info struct caller { @@ -78,20 +83,20 @@ class rpcc : private connection_delegate { request dup_req_; int xid_rep_done_; - int call1(proc_t proc, marshall &req, string &rep, milliseconds to); + int call1(proc_id_t proc, marshall &req, string &rep, milliseconds to); template - int call_m(proc_t proc, marshall &req, R & r, milliseconds to) { + int call_m(proc_id_t proc, marshall &req, R & r, milliseconds to) { string rep; int intret = call1(proc, req, rep, to); unmarshall u(rep, true); if (intret < 0) return intret; u >> r; if (u.okdone() != true) { - cerr << "rpcc::call_m: failed to unmarshall the reply. You are probably " << - "calling RPC 0x" << hex << proc << " with the wrong return type." << endl; + LOG("rpcc::call_m: failed to unmarshall the reply. You are probably " << + "calling RPC 0x" << hex << proc << " with the wrong return type."); VERIFY(0); - return rpc_const::unmarshal_reply_failure; + return rpc_protocol::unmarshal_reply_failure; } return intret; } @@ -111,21 +116,25 @@ class rpcc : private connection_delegate { void cancel(); - template - inline int call(proc_t proc, R & r, const Args&... args) { + template + inline int call(proc_t

proc, R & r, const Args&... args) { return call_timeout(proc, rpc::to_max, r, args...); } - template - inline int call_timeout(proc_t proc, milliseconds to, R & r, const Args&... args) { + template + inline int call_timeout(proc_t

proc, milliseconds to, R & r, const Args&... args) { + static_assert(is_valid_call::value, "RPC called with incorrect argument types"); marshall m{args...}; - return call_m(proc, m, r, to); + return call_m(proc.id, m, r, to); } }; // rpc server endpoint. class rpcs : private connection_delegate { private: + using proc_id_t = rpc_protocol::proc_id_t; + template + using proc_t = rpc_protocol::proc_t; typedef enum { NEW, // new RPC, not a duplicate @@ -160,7 +169,7 @@ class rpcs : private connection_delegate { rpcstate_t checkduplicate_and_update(unsigned int clt_nonce, int xid, int rep_xid, string & b); - void updatestat(proc_t proc); + void updatestat(proc_id_t proc); // latest connection to the client map> conns_; @@ -168,12 +177,12 @@ class rpcs : private connection_delegate { // counting const size_t counting_; size_t curr_counts_; - map counts_; + map counts_; bool reachable_; // map proc # to function - map procs_; + map procs_; mutex procs_m_; // protect insert/delete to procs[] mutex count_m_; // protect modification of counts @@ -183,13 +192,13 @@ class rpcs : private connection_delegate { void dispatch(shared_ptr c, const string & buf); // internal handler registration - void reg1(proc_t proc, handler *); + void reg1(proc_id_t proc, handler *); unique_ptr dispatchpool_; unique_ptr listener_; // RPC handler for clients binding - int rpcbind(unsigned int &r, int a); + rpc_protocol::status rpcbind(unsigned int &r, int a); bool got_pdu(const shared_ptr & c, const string & b); @@ -200,13 +209,14 @@ class rpcs : private connection_delegate { void set_reachable(bool r) { reachable_ = r; } - template void reg(proc_t proc, F f, C *c=nullptr) { + template void reg(proc_t

proc, F f, C *c=nullptr) { + static_assert(is_valid_registration::value, "RPC handler registered with incorrect argument types"); struct ReturnOnFailure { static inline int unmarshall_args_failure() { - return rpc_const::unmarshal_args_failure; + return rpc_protocol::unmarshal_args_failure; } }; - reg1(proc, marshalled_func::wrap(f, c)); + reg1(proc.id, marshalled_func::wrap(f, c)); } void start();