From: Peter Iannucci Date: Fri, 17 Jan 2014 11:40:08 +0000 (-0500) Subject: RPC procedures are now identified via a struct containing a string name. X-Git-Url: http://xvm.mit.edu/gitweb/invirt/third/libt4.git/commitdiff_plain/02967a43024ce81912cd1ec96a800397457f8066 RPC procedures are now identified via a struct containing a string name. --- diff --git a/rpc/rpc.cc b/rpc/rpc.cc index a74d907..8f868f5 100644 --- a/rpc/rpc.cc +++ b/rpc/rpc.cc @@ -145,14 +145,15 @@ void rpcc::cancel(lock & m_lock) { } } -int rpcc::call_marshalled(proc_id_t proc, milliseconds to, string & rep, marshall & req) { +int rpcc::call_marshalled(const rpc_protocol::proc_t & proc, milliseconds to, string & rep, const marshall & req) { caller ca(0, &rep); xid_t xid_rep; + marshall datagram = req; { lock ml(m_); - if ((proc != rpc_protocol::bind.id && !bind_done_) || (proc == rpc_protocol::bind.id && bind_done_)) { + if ((proc.id != rpc_protocol::bind.id && !bind_done_) || (proc.id == rpc_protocol::bind.id && bind_done_)) { IF_LEVEL(1) LOG << "rpcc has not been bound to dst or binding twice"; return rpc_protocol::bind_failure; } @@ -163,8 +164,8 @@ int rpcc::call_marshalled(proc_id_t proc, milliseconds to, string & rep, marshal ca.xid = xid_++; calls_[ca.xid] = &ca; - req.write_header(rpc_protocol::request_header{ - ca.xid, proc, clt_nonce_, srv_nonce_, xid_rep_window_.front() + datagram.write_header(rpc_protocol::request_header{ + ca.xid, proc.id, clt_nonce_, srv_nonce_, xid_rep_window_.front() }); xid_rep = xid_rep_window_.front(); } @@ -190,10 +191,10 @@ int rpcc::call_marshalled(proc_id_t proc, milliseconds to, string & rep, marshal } if (forgot.isvalid()) ch->send(forgot.buf); - ch->send(req); + ch->send(datagram); } else IF_LEVEL(1) LOG << "not reachable"; - IF_LEVEL(2) LOG << clt_nonce_ << " just sent req proc " << std::hex << proc + IF_LEVEL(2) LOG << clt_nonce_ << " just sent req proc " << std::hex << proc.id << " xid " << std::dec << ca.xid << " clt_nonce " << clt_nonce_; } transmit = false; // only send once on a given channel @@ -242,7 +243,7 @@ int rpcc::call_marshalled(proc_id_t proc, milliseconds to, string & rep, marshal { lock ml(m_); if (!dup_req_.isvalid()) { - dup_req_.buf = req; + dup_req_.buf = datagram; dup_req_.xid = ca.xid; } if (xid_rep > xid_rep_done_) @@ -251,7 +252,7 @@ int rpcc::call_marshalled(proc_id_t proc, milliseconds to, string & rep, marshal lock cal(ca.m); - IF_LEVEL(2) LOG << clt_nonce_ << " call done for req proc " << std::hex << proc + IF_LEVEL(2) LOG << clt_nonce_ << " call done for req proc " << std::hex << proc.id << " xid " << std::dec << ca.xid << " " << inet_ntoa(dst_.sin_addr) << ":" << ntoh(dst_.sin_port) << " done? " << ca.done << " ret " << ca.intret; @@ -373,7 +374,7 @@ void rpcs::dispatch(shared_ptr c, const string & buf) { // is client sending to an old instance of server? if (h.srv_nonce != 0 && h.srv_nonce != nonce_) { IF_LEVEL(2) LOG << "rpc for an old server instance " << h.srv_nonce - << " (current " << nonce_ << ") proc " << std::hex << h.proc; + << " (current " << nonce_ << ") proc " << std::hex << proc; rh.ret = rpc_protocol::oldsrv_failure; rep.write_header(rh); c->send(rep); diff --git a/rpc/rpc.h b/rpc/rpc.h index ddf15f9..9464e57 100644 --- a/rpc/rpc.h +++ b/rpc/rpc.h @@ -42,8 +42,6 @@ struct is_valid_registration< class rpcc : private connection_delegate { private: using proc_id_t = rpc_protocol::proc_id_t; - template - using proc_t = rpc_protocol::proc_t; using nonce_t = rpc_protocol::nonce_t; using xid_t = rpc_protocol::xid_t; @@ -94,16 +92,7 @@ class rpcc : private connection_delegate { request dup_req_; int xid_rep_done_ = -1; - int call_marshalled(proc_id_t proc, milliseconds to, string & rep, marshall & req); - - template - inline int call_m(proc_id_t proc, milliseconds to, R & r, marshall && req) { - string rep; - int intret = call_marshalled(proc, to, rep, req); - if (intret >= 0) - VERIFY(unmarshall(rep, true, r).okdone()); // guaranteed by static type checking - return intret; - } + int call_marshalled(const rpc_protocol::proc_t & proc, milliseconds to, string & rep, const marshall & req); bool got_pdu(const shared_ptr & c, const string & b); @@ -127,14 +116,19 @@ class rpcc : private connection_delegate { void cancel(lock & m_lock); template - inline int call(proc_t

proc, R & r, const Args & ... args) { + inline int call(const rpc_protocol::proc_checked_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) { + inline int call_timeout(const rpc_protocol::proc_checked_t

& proc, milliseconds to, R & r, const Args & ... args) { static_assert(is_valid_call::value, "RPC called with incorrect argument types"); - return call_m(proc.id, to, r, std::forward(marshall(args...))); + string rep; + int intret = call_marshalled(proc, to, rep, marshall(args...)); + if (intret >= 0) { + VERIFY(unmarshall(rep, true, r).okdone()); // guaranteed by static type checking + } + return intret; } }; @@ -142,8 +136,6 @@ class rpcc : private connection_delegate { class rpcs : private connection_delegate { private: using proc_id_t = rpc_protocol::proc_id_t; - template - using proc_t = rpc_protocol::proc_t; using nonce_t = rpc_protocol::nonce_t; using xid_t = rpc_protocol::xid_t; @@ -208,7 +200,8 @@ class rpcs : private connection_delegate { void set_reachable(bool r) { reachable_ = r; } - template inline void reg(proc_t

proc, F f, C *c=nullptr) { + template + inline void reg(const rpc_protocol::proc_checked_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() { diff --git a/rpc/rpc_protocol.h b/rpc/rpc_protocol.h index 80089ff..4f03937 100644 --- a/rpc/rpc_protocol.h +++ b/rpc/rpc_protocol.h @@ -38,10 +38,15 @@ namespace rpc_protocol { MEMBERS(xid, ret) }; - template struct proc_t { - using signature = Signature; proc_id_t id; + const char * name; + }; + + template + struct proc_checked_t : proc_t { + using signature = Signature; + constexpr inline proc_checked_t(proc_id_t id, const char * name) : proc_t{id, name} {} }; union header_t { request_header req; reply_header rep; }; @@ -49,8 +54,11 @@ namespace rpc_protocol { const size_t DEFAULT_RPC_SZ = 1024; // size of initial buffer allocation const size_t MAX_PDU = 10<<20; // maximum PDF is 10M -#define REMOTE_PROCEDURE_BASE(_base_) static constexpr rpc_protocol::proc_id_t base = _base_ -#define REMOTE_PROCEDURE(_offset_, _name_, _args_) static constexpr rpc_protocol::proc_t _name_{base + _offset_} +#define REMOTE_PROCEDURE_BASE(_base_) \ + static constexpr rpc_protocol::proc_id_t base = _base_ + +#define REMOTE_PROCEDURE(_offset_, _name_, _args_) \ + static constexpr rpc_protocol::proc_checked_t _name_{base + _offset_, #_name_} REMOTE_PROCEDURE_BASE(0); REMOTE_PROCEDURE(1, bind, (nonce_t &)); // handler number reserved for bind diff --git a/rsm.h b/rsm.h index dfbb25c..487a856 100644 --- a/rsm.h +++ b/rsm.h @@ -71,7 +71,7 @@ class rsm : public config_view_change { void set_state_transfer(rsm_state_transfer *_stf) { stf = _stf; } void commit_change(unsigned vid); - template void reg(rpc_protocol::proc_t

proc, F f, C *c=nullptr) { + template void reg(rpc_protocol::proc_checked_t

proc, F f, C *c=nullptr) { static_assert(is_valid_registration::value, "RSM handler registered with incorrect argument types"); lock ml(rsm_mutex); procs[proc.id] = marshalled_func::wrap(f, c); diff --git a/rsm_client.h b/rsm_client.h index 90b5b06..32dde43 100644 --- a/rsm_client.h +++ b/rsm_client.h @@ -19,15 +19,15 @@ class rsm_client { std::mutex rsm_client_mutex; void primary_failure(lock & rsm_client_mutex_lock); bool init_members(lock & rsm_client_mutex_lock); - rsm_protocol::status invoke(unsigned int proc, string & rep, const string & req); - template int call_m(unsigned int proc, R & r, const marshall & req); + rsm_protocol::status invoke(rpc_protocol::proc_id_t proc, string & rep, const string & req); + template int call_marshalled(rpc_protocol::proc_t & proc, R & r, const marshall & req); public: rsm_client(string dst); template - inline int call(rpc_protocol::proc_t

proc, R & r, const Args & ...a1) { + inline int call(rpc_protocol::proc_checked_t

proc, R & r, const Args & ...a1) { static_assert(is_valid_call::value, "RSM method invoked with incorrect argument types"); - return call_m(proc.id, r, marshall(a1...)); + return call_marshalled(proc, r, marshall(a1...)); } }; @@ -41,9 +41,9 @@ inline string hexify(const string & s) { } template -int rsm_client::call_m(unsigned int proc, R & r, const marshall & req) { +int rsm_client::call_marshalled(rpc_protocol::proc_t & proc, R & r, const marshall & req) { string rep; - int intret = invoke(proc, rep, req.content()); + int intret = invoke(proc.id, rep, req.content()); VERIFY( intret == rsm_client_protocol::OK ); unmarshall u(rep, false, intret); if (intret < 0) return intret; @@ -53,15 +53,15 @@ int rsm_client::call_m(unsigned int proc, R & r, const marshall & req) { LOG << "failed to unmarshall the reply."; LOG << "You probably forgot to set the reply string in " << "rsm::client_invoke, or you may have called RPC " - << "0x" << std::hex << proc << " with the wrong return type"; + << proc.name << " (0x" << std::hex << proc.id << ") with the wrong return type"; LOG << "here's what I got: \"" << hexify(rep) << "\""; VERIFY(0); return rpc_protocol::unmarshall_reply_failure; } if(!unmarshall(res, false, r).okdone()) { LOG << "failed to unmarshall the reply."; - LOG << "You are probably calling RPC 0x" << std::hex << proc - << " with the wrong return type."; + LOG << "You are probably calling RPC " << proc.name << " (0x" + << std::hex << proc.id << ") with the wrong return type."; LOG << "here's what I got: \"" << hexify(res) << "\""; VERIFY(0); return rpc_protocol::unmarshall_reply_failure;