user_args::~user_args () { if (args) xdr_delete (prog->tbl[procno].xdr_arg, args); }
void chord::dispatch (ptr<asrv> s, svccb *sbp) { if (!sbp) { s->setcb (NULL); return; } (*nrcv)++; dorpc_arg *arg = sbp->Xtmpl getarg<dorpc_arg> (); switch (sbp->proc ()) { case TRANSPORTPROC_NULL: sbp->reply (NULL); break; case TRANSPORTPROC_DORPC: { chordID v = make_chordID (arg->dest); vnode *vnodep = vnodes[v]; if (!vnodep) { trace << "unknown vnode " << v << " for procedure " << sbp->proc () << " (" << arg->progno << "." << arg->procno << ").\n"; sbp->replyref (rpcstat (DORPC_UNKNOWNNODE)); return; } //find the program const rpc_program *prog = get_program (arg->progno); if (!prog) { sbp->replyref (rpcstat (DORPC_NOHANDLER)); return; } //unmarshall the args char *arg_base = (char *)(arg->args.base ()); int arg_len = arg->args.size (); xdrmem x (arg_base, arg_len, XDR_DECODE); xdrproc_t proc = prog->tbl[arg->procno].xdr_arg; assert (proc); void *unmarshalled_args = prog->tbl[arg->procno].alloc_arg (); if (!proc (x.xdrp (), unmarshalled_args)) { warn << "dispatch: error unmarshalling arguments: " << arg->progno << "." << arg->procno << " from " << v <<"\n"; xdr_delete (prog->tbl[arg->procno].xdr_arg, unmarshalled_args); sbp->replyref (rpcstat (DORPC_MARSHALLERR)); return; } //call the handler user_args *ua = New user_args (sbp, unmarshalled_args, prog, arg->procno, arg->send_time); vnodep->fill_user_args (ua); if (!vnodep->progHandled (arg->progno)) { trace << "dispatch to vnode " << v << " doesn't handle " << arg->progno << "." << arg->procno << "\n"; ua->replyref (chordstat (CHORD_NOHANDLER)); } else { cbdispatch_t dispatch = vnodep->getHandler(arg->progno); (dispatch)(ua); } } break; default: warn << "Transport procedure " << sbp->proc () << " not handled\n"; } }