*.a
*.log
rsm_tester
+config
ml.unlock();
rpcc *cl = h.safebind();
if (cl) {
- ret = cl->call(paxos_protocol::heartbeat, me, vid, r,
- rpcc::to(1000));
+ ret = cl->call_timeout(paxos_protocol::heartbeat, rpcc::to(1000), r, me, vid);
}
ml.lock();
}
lock_client::stat(lock_protocol::lockid_t lid)
{
int r;
- lock_protocol::status ret = cl->call(lock_protocol::stat, cl->id(), lid, r);
+ lock_protocol::status ret = cl->call(lock_protocol::stat, r, cl->id(), lid);
VERIFY (ret == lock_protocol::OK);
return r;
}
lock_client::acquire(lock_protocol::lockid_t lid)
{
int r;
- return cl->call(lock_protocol::acquire, cl->id(), lid, r);
+ return cl->call(lock_protocol::acquire, r, cl->id(), lid);
}
lock_protocol::status
lock_client::release(lock_protocol::lockid_t lid)
{
int r;
- return cl->call(lock_protocol::release, cl->id(), lid, r);
+ return cl->call(lock_protocol::release, r, cl->id(), lid);
}
t4_lock_client *t4_lock_client_new(const char *dst) {
{
sl.unlock();
int r;
- rsmc->call(lock_protocol::release, lid, id, st.xid, r);
+ rsmc->call(lock_protocol::release, r, lid, id, st.xid);
sl.lock();
}
st.state = lock_state::none;
{
sl.unlock();
int r;
- result = rsmc->call(lock_protocol::acquire, lid, id, st.xid, r);
+ result = rsmc->call(lock_protocol::acquire, r, lid, id, st.xid);
sl.lock();
}
LOG("acquire returned " << result);
proxy = handle(held_by.first).safebind();
if (proxy) {
int r;
- rlock_protocol::status ret = proxy->call(rlock_protocol::revoke, lid, held_by.second, r);
+ rlock_protocol::status ret = proxy->call(rlock_protocol::revoke, r, lid, held_by.second);
LOG("Revoke returned " << ret);
}
}
proxy = handle(front.first).safebind();
if (proxy) {
int r;
- ret = proxy->call(rlock_protocol::retry, lid, front.second, r);
+ ret = proxy->call(rlock_protocol::retry, r, lid, front.second);
LOG("Retry returned " << ret);
}
}
handle h(*i);
if (!(r = h.safebind()))
continue;
- int status = r->call(paxos_protocol::preparereq, me, arg, res, rpcc::to(1000));
+ int status = r->call_timeout(paxos_protocol::preparereq, rpcc::to(1000), res, me, arg);
if (status == paxos_protocol::OK) {
if (res.oldinstance) {
tprintf("commiting old instance!\n");
if (!(r = h.safebind()))
continue;
bool accept = false;
- int status = r->call(paxos_protocol::acceptreq, me, arg, accept, rpcc::to(1000));
+ int status = r->call_timeout(paxos_protocol::acceptreq, rpcc::to(1000), accept, me, arg);
if (status == paxos_protocol::OK) {
if (accept)
accepts.push_back(*i);
if (!(r = h.safebind()))
continue;
int res = 0;
- r->call(paxos_protocol::decidereq, me, arg, res, rpcc::to(1000));
+ r->call_timeout(paxos_protocol::decidereq, rpcc::to(1000), res, me, arg);
}
}
#define DEFAULT_RPC_SZ 1024
#define RPC_HEADER_SZ (std::max(sizeof(req_header), sizeof(reply_header)) + sizeof(rpc_sz_t))
+struct pass {
+ template<typename... Args> inline pass(Args&&...) {}
+};
+
class marshall {
private:
char *_buf; // Base of the raw bytes buffer (dynamically readjusted)
_ind = RPC_HEADER_SZ;
}
+ template <typename... Args> marshall(const Args&... args) : marshall() {
+ (void)pass{(*this << args)...};
+ }
+
~marshall() {
if (_buf)
free(_buf);
unpack(&h->ret);
_ind = RPC_HEADER_SZ;
}
+
+ template <class OutputIterator>
+ void iterate(OutputIterator i, int n) {
+ while (n--) {
+ typename OutputIterator::value_type t;
+ *this >> t;
+ *i++ = t;
+ }
+ }
};
unmarshall& operator>>(unmarshall &, bool &);
rpcc::bind(TO to)
{
int r;
- int ret = call(rpc_const::bind, 0, r, to);
+ int ret = call_timeout(rpc_const::bind, to, r, 0);
if(ret == 0){
lock ml(m_);
bind_done_ = true;
template<class R>
int call_m(unsigned int proc, marshall &req, R & r, TO to);
- template<class R>
- int call(unsigned int proc, R & r, TO to = to_max);
- template<class R, class A1>
- int call(unsigned int proc, const A1 & a1, R & r, TO to = to_max);
- template<class R, class A1, class A2>
- int call(unsigned int proc, const A1 & a1, const A2 & a2, R & r,
- TO to = to_max);
- template<class R, class A1, class A2, class A3>
- int call(unsigned int proc, const A1 & a1, const A2 & a2, const A3 & a3,
- R & r, TO to = to_max);
- template<class R, class A1, class A2, class A3, class A4>
- int call(unsigned int proc, const A1 & a1, const A2 & a2, const A3 & a3,
- const A4 & a4, R & r, TO to = to_max);
- template<class R, class A1, class A2, class A3, class A4, class A5>
- int call(unsigned int proc, const A1 & a1, const A2 & a2, const A3 & a3,
- const A4 & a4, const A5 & a5, R & r, TO to = to_max);
- template<class R, class A1, class A2, class A3, class A4, class A5,
- class A6>
- int call(unsigned int proc, const A1 & a1, const A2 & a2, const A3 & a3,
- const A4 & a4, const A5 & a5, const A6 & a6,
- R & r, TO to = to_max);
- template<class R, class A1, class A2, class A3, class A4, class A5,
- class A6, class A7>
- int call(unsigned int proc, const A1 & a1, const A2 & a2, const A3 & a3,
- const A4 & a4, const A5 & a5, const A6 &a6, const A7 &a7,
- R & r, TO to = to_max);
+ template<class R, typename ...Args>
+ inline int call(unsigned int proc, R & r, const Args&... args);
+ template<class R, typename ...Args>
+ inline int call_timeout(unsigned int proc, TO to, R & r, const Args&... args);
};
template<class R> int
rpcc::call_m(unsigned int proc, marshall &req, R & r, TO to)
{
- unmarshall u;
- int intret = call1(proc, req, u, to);
- if (intret < 0) return intret;
- u >> r;
- if(u.okdone() != true) {
- fprintf(stderr, "rpcc::call_m: failed to unmarshall the reply."
- "You are probably calling RPC 0x%x with wrong return "
- "type.\n", proc);
- VERIFY(0);
- return rpc_const::unmarshal_reply_failure;
- }
- return intret;
-}
-
-template<class R> int
-rpcc::call(unsigned int proc, R & r, TO to)
-{
- marshall m;
- return call_m(proc, m, r, to);
-}
-
-template<class R, class A1> int
-rpcc::call(unsigned int proc, const A1 & a1, R & r, TO to)
-{
- marshall m;
- m << a1;
- return call_m(proc, m, r, to);
-}
-
-template<class R, class A1, class A2> int
-rpcc::call(unsigned int proc, const A1 & a1, const A2 & a2,
- R & r, TO to)
-{
- marshall m;
- m << a1;
- m << a2;
- return call_m(proc, m, r, to);
-}
-
-template<class R, class A1, class A2, class A3> int
-rpcc::call(unsigned int proc, const A1 & a1, const A2 & a2,
- const A3 & a3, R & r, TO to)
-{
- marshall m;
- m << a1;
- m << a2;
- m << a3;
- return call_m(proc, m, r, to);
+ unmarshall u;
+ int intret = call1(proc, req, u, to);
+ if (intret < 0) return intret;
+ u >> r;
+ if (u.okdone() != true) {
+ fprintf(stderr, "rpcc::call_m: failed to unmarshall the reply."
+ "You are probably calling RPC 0x%x with wrong return "
+ "type.\n", proc);
+ VERIFY(0);
+ return rpc_const::unmarshal_reply_failure;
+ }
+ return intret;
}
-template<class R, class A1, class A2, class A3, class A4> int
-rpcc::call(unsigned int proc, const A1 & a1, const A2 & a2,
- const A3 & a3, const A4 & a4, R & r, TO to)
+template<class R, typename... Args> inline int
+rpcc::call(unsigned int proc, R & r, const Args&... args)
{
- marshall m;
- m << a1;
- m << a2;
- m << a3;
- m << a4;
- return call_m(proc, m, r, to);
-}
-
-template<class R, class A1, class A2, class A3, class A4, class A5> int
-rpcc::call(unsigned int proc, const A1 & a1, const A2 & a2,
- const A3 & a3, const A4 & a4, const A5 & a5, R & r, TO to)
-{
- marshall m;
- m << a1;
- m << a2;
- m << a3;
- m << a4;
- m << a5;
- return call_m(proc, m, r, to);
-}
-
-template<class R, class A1, class A2, class A3, class A4, class A5,
- class A6> int
-rpcc::call(unsigned int proc, const A1 & a1, const A2 & a2,
- const A3 & a3, const A4 & a4, const A5 & a5,
- const A6 & a6, R & r, TO to)
-{
- marshall m;
- m << a1;
- m << a2;
- m << a3;
- m << a4;
- m << a5;
- m << a6;
- return call_m(proc, m, r, to);
+ return call_timeout(proc, rpcc::to_max, r, args...);
}
-template<class R, class A1, class A2, class A3, class A4, class A5,
- class A6, class A7> int
-rpcc::call(unsigned int proc, const A1 & a1, const A2 & a2,
- const A3 & a3, const A4 & a4, const A5 & a5,
- const A6 & a6, const A7 & a7,
- R & r, TO to)
+template<class R, typename... Args> inline int
+rpcc::call_timeout(unsigned int proc, const rpcc::TO to, R & r, const Args&... args)
{
- marshall m;
- m << a1;
- m << a2;
- m << a3;
- m << a4;
- m << a5;
- m << a6;
- m << a7;
+ marshall m{args...};
return call_m(proc, m, r, to);
}
for(int i = 0; i < 100; i++){
int arg = (random() % 2000);
std::string rep;
- int ret = clients[which_cl]->call(25, arg, rep);
+ int ret = clients[which_cl]->call(25, rep, arg);
VERIFY(ret == 0);
if ((int)rep.size()!=arg) {
printf("repsize wrong %d!=%d\n", (int)rep.size(), arg);
auto start = std::chrono::steady_clock::now();
- int ret = clients[which_cl]->call(which ? 23 : 24, arg, rep);
+ int ret = clients[which_cl]->call(which ? 23 : 24, rep, arg);
auto end = std::chrono::steady_clock::now();
int diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
if (ret != 0)
while(time(0) - t1 < 10){
int arg = (random() % 2000);
std::string rep;
- int ret = clients[which_cl]->call(25, arg, rep);
+ int ret = clients[which_cl]->call(25, rep, arg);
if ((int)rep.size()!=arg) {
printf("ask for %d reply got %d ret %d\n",
arg, (int)rep.size(), ret);
for(int i = 0; i < 4; i++){
int rep;
- int ret = c->call(24, i, rep, rpcc::to(3000));
+ int ret = c->call_timeout(24, rpcc::to(3000), rep, i);
VERIFY(ret == rpc_const::timeout_failure || rep == i+2);
}
}
// to marshall the RPC call packet, and how to unmarshall
// the reply packet.
std::string rep;
- int intret = c->call(22, (std::string)"hello", (std::string)" goodbye", rep);
+ int intret = c->call(22, rep, (std::string)"hello", (std::string)" goodbye");
VERIFY(intret == 0); // this is what handle_22 returns
VERIFY(rep == "hello goodbye");
printf(" -- string concat RPC .. ok\n");
// small request, big reply (perhaps req via UDP, reply via TCP)
- intret = c->call(25, 70000, rep, rpcc::to(200000));
+ intret = c->call_timeout(25, rpcc::to(200000), rep, 70000);
VERIFY(intret == 0);
VERIFY(rep.size() == 70000);
printf(" -- small request, big reply .. ok\n");
// specify a timeout value to an RPC that should succeed (udp)
int xx = 0;
- intret = c->call(23, 77, xx, rpcc::to(3000));
+ intret = c->call_timeout(23, rpcc::to(3000), xx, 77);
VERIFY(intret == 0 && xx == 78);
printf(" -- no suprious timeout .. ok\n");
{
std::string arg(1000, 'x');
std::string rep;
- c->call(22, arg, (std::string)"x", rep, rpcc::to(3000));
+ c->call_timeout(22, rpcc::to(3000), rep, arg, (std::string)"x");
VERIFY(rep.size() == 1001);
printf(" -- no suprious timeout .. ok\n");
}
// huge RPC
std::string big(1000000, 'x');
- intret = c->call(22, big, (std::string)"z", rep);
+ intret = c->call(22, rep, big, (std::string)"z");
VERIFY(rep.size() == 1000001);
printf(" -- huge 1M rpc request .. ok\n");
startserver();
std::string rep;
- int intret = client->call(22, (std::string)"hello", (std::string)" goodbye", rep);
+ int intret = client->call(22, rep, (std::string)"hello", (std::string)" goodbye");
VERIFY(intret == rpc_const::oldsrv_failure);
printf(" -- call recovered server with old client .. failed ok\n");
VERIFY (client->bind() >= 0);
VERIFY (client->bind() < 0);
- intret = client->call(22, (std::string)"hello", (std::string)" goodbye", rep);
+ intret = client->call(22, rep, (std::string)"hello", (std::string)" goodbye");
VERIFY(intret == 0);
VERIFY(rep == "hello goodbye");
ml.unlock();
cl = h.safebind();
if (cl) {
- ret = cl->call(rsm_protocol::transferreq, cfg->myaddr(),
- last_myvs, vid_insync, r, rpcc::to(1000));
+ ret = cl->call_timeout(rsm_protocol::transferreq, rpcc::to(1000),
+ r, cfg->myaddr(), last_myvs, vid_insync);
}
ml.lock();
}
bool done = false;
if (cl) {
int r;
- rsm_protocol::status ret = cl->call(rsm_protocol::transferdonereq, cfg->myaddr(), vid_insync, r);
+ rsm_protocol::status ret = cl->call(rsm_protocol::transferdonereq, r, cfg->myaddr(), vid_insync);
done = (ret == rsm_protocol::OK);
}
ml.lock();
ml.unlock();
cl = h.safebind();
if (cl != 0) {
- ret = cl->call(rsm_protocol::joinreq, cfg->myaddr(), last_myvs,
- r, rpcc::to(120000));
+ ret = cl->call_timeout(rsm_protocol::joinreq, rpcc::to(120000), r,
+ cfg->myaddr(), last_myvs);
}
ml.lock();
}
return rsm_client_protocol::BUSY;
rsm_protocol::status ret;
int r;
- ret = cl->call(rsm_protocol::invoke, procno, vs, req, r, rpcc::to(1000));
+ ret = cl->call_timeout(rsm_protocol::invoke, rpcc::to(1000), r, procno, vs, req);
LOG("Invoke returned " << ret);
if (ret != rsm_protocol::OK)
return rsm_client_protocol::BUSY;
ml.unlock();
rpcc *cl = h.safebind();
if (cl)
- ret = cl->call(rsm_client_protocol::invoke, proc, req, rep, rpcc::to(5000));
+ ret = cl->call_timeout(rsm_client_protocol::invoke, rpcc::to(5000), rep, proc, req);
ml.lock();
if (!cl)
ml.unlock();
cl = h.safebind();
if (cl) {
- ret = cl->call(rsm_client_protocol::members, 0, known_mems,
- rpcc::to(1000));
+ ret = cl->call_timeout(rsm_client_protocol::members, rpcc::to(1000), known_mems, 0);
}
ml.lock();
}
rsmtest_client::net_repair(int heal)
{
int r;
- int ret = cl->call(rsm_test_protocol::net_repair, heal, r);
+ int ret = cl->call(rsm_test_protocol::net_repair, r, heal);
VERIFY (ret == rsm_test_protocol::OK);
return r;
}
rsmtest_client::breakpoint(int b)
{
int r;
- int ret = cl->call(rsm_test_protocol::breakpoint, b, r);
+ int ret = cl->call(rsm_test_protocol::breakpoint, r, b);
VERIFY (ret == rsm_test_protocol::OK);
return r;
}