rpc_ctx_t * alloc_rpc_call_ctx(CLIENT *clnt, rpcproc_t proc, xdrproc_t xdr_args, void *args_ptr, xdrproc_t xdr_results, void *results_ptr, struct timeval timeout) { struct x_vc_data *xd = (struct x_vc_data *) clnt->cl_p1; struct rpc_dplx_rec *rec = xd->rec; rpc_ctx_t *ctx; ctx = mem_alloc(sizeof(rpc_ctx_t)); if (! ctx) goto out; /* potects this */ mutex_init(&ctx->we.mtx, NULL); cond_init(&ctx->we.cv, 0, NULL); /* rec->calls and rbtree protected by (adaptive) mtx */ mutex_lock(&rec->mtx); /* XXX we hold the client-fd lock */ ctx->xid = ++(xd->cx.calls.xid); /* some of this looks like overkill; it's here to support future, * fully async calls */ ctx->ctx_u.clnt.clnt = clnt; ctx->ctx_u.clnt.timeout.tv_sec = 0; ctx->ctx_u.clnt.timeout.tv_nsec = 0; timespec_addms(&ctx->ctx_u.clnt.timeout, tv_to_ms(&timeout)); ctx->msg = alloc_rpc_msg(); ctx->flags = 0; /* stash it */ if (opr_rbtree_insert(&xd->cx.calls.t, &ctx->node_k)) { __warnx(TIRPC_DEBUG_FLAG_RPC_CTX, "%s: call ctx insert failed (xid %d client %p)", __func__, ctx->xid, clnt); mutex_unlock(&rec->mtx); mem_free(ctx, sizeof(rpc_ctx_t)); ctx = NULL; goto out; } mutex_unlock(&rec->mtx); out: return (ctx); }
static bool svc_rdma_recv(SVCXPRT *xprt, struct svc_req *req) { struct rpc_rdma_cbc *cbc = req->rq_context; XDR *xdrs = cbc->holdq.xdrs; __warnx(TIRPC_DEBUG_FLAG_SVC_RDMA, "%s() xprt %p cbc %p incoming xdr %p\n", __func__, xprt, cbc, xdrs); req->rq_msg = alloc_rpc_msg(); if (!xdr_rdma_svc_recv(cbc, 0)){ __warnx(TIRPC_DEBUG_FLAG_SVC_RDMA, "%s: xdr_rdma_svc_recv failed", __func__); return (FALSE); } xdrs->x_op = XDR_DECODE; /* No need, already positioned to beginning ... XDR_SETPOS(xdrs, 0); */ if (!xdr_dplx_decode(xdrs, req->rq_msg)) { __warnx(TIRPC_DEBUG_FLAG_SVC_RDMA, "%s: xdr_dplx_decode failed", __func__); return (FALSE); } req->rq_xprt = xprt; req->rq_prog = req->rq_msg->rm_call.cb_prog; req->rq_vers = req->rq_msg->rm_call.cb_vers; req->rq_proc = req->rq_msg->rm_call.cb_proc; req->rq_xid = req->rq_msg->rm_xid; req->rq_clntcred = req->rq_msg->rq_cred_body; /* the checksum */ req->rq_cksum = 0; return (TRUE); }