X-Git-Url: http://xvm.mit.edu/gitweb/invirt/third/libt4.git/blobdiff_plain/eeab3e6cade87c1fe0a5f3d93522e12ccb9ec2ab..e0c49ff6ba44cf5b47ab91d58b67763f5a1c7a58:/rsm_client.h diff --git a/rsm_client.h b/rsm_client.h index 5d0cd71..90b5b06 100644 --- a/rsm_client.h +++ b/rsm_client.h @@ -1,11 +1,8 @@ #ifndef rsm_client_h #define rsm_client_h -#include "rpc/rpc.h" +#include "types.h" #include "rsm_protocol.h" -#include -#include - // // rsm client interface. @@ -17,54 +14,59 @@ class rsm_client { protected: - std::string primary; - std::vector known_mems; + string primary; + std::vector known_mems; std::mutex rsm_client_mutex; - void primary_failure(); - bool init_members(); + 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); public: - rsm_client(std::string dst); - rsm_protocol::status invoke(unsigned int proc, std::string &rep, const std::string &req); + rsm_client(string dst); - template - int call(unsigned int proc, R & r, const Args & ...a1); - private: - template int call_m(unsigned int proc, R & r, const marshall & req); + template + inline int call(rpc_protocol::proc_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...)); + } }; -template -int rsm_client::call_m(unsigned int proc, R & r, const marshall & req) { - std::string rep; - std::string res; - int intret = invoke(proc, rep, req.cstr()); - VERIFY( intret == rsm_client_protocol::OK ); - unmarshall u(rep); - u >> intret; - if (intret < 0) return intret; - u >> res; - if (!u.okdone()) { - fprintf(stderr, "rsm_client::call_m: failed to unmarshall the reply.\n" - "You probably forgot to set the reply string in " - "rsm::client_invoke, or you may call RPC 0x%x with wrong return " - "type\n", proc); - VERIFY(0); - return rpc_const::unmarshal_reply_failure; - } - unmarshall u1(res); - u1 >> r; - if(!u1.okdone()) { - fprintf(stderr, "rsm_client::call_m: failed to unmarshall the reply.\n" - "You are probably calling RPC 0x%x with wrong return " - "type.\n", proc); - VERIFY(0); - return rpc_const::unmarshal_reply_failure; - } - return intret; +inline string hexify(const string & s) { + string bytes; + for (char ch : s) { + bytes.push_back("0123456789abcdef"[(uint8_t)ch >> 4]); + bytes.push_back("0123456789abcdef"[(uint8_t)ch & 15]); + } + return bytes; } -template -int rsm_client::call(unsigned int proc, R & r, const Args & ...a1) { - return call_m(proc, r, marshall{a1...}); +template +int rsm_client::call_m(unsigned int proc, R & r, const marshall & req) { + string rep; + int intret = invoke(proc, rep, req.content()); + VERIFY( intret == rsm_client_protocol::OK ); + unmarshall u(rep, false, intret); + if (intret < 0) return intret; + string res; + u >> res; + if (!u.okdone()) { + 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"; + 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 << "here's what I got: \"" << hexify(res) << "\""; + VERIFY(0); + return rpc_protocol::unmarshall_reply_failure; + } + return intret; } #endif