int sp_recv (int eid, char **ubuf) { struct epbase *ep = eid_get (eid); if (!ep) { ERRNO_RETURN (EBADF); } mutex_lock (&ep->lock); /* All the received message would saved in the rcv.head. if the endpoint * status ok and the rcv.head is empty, we wait here. when the endpoint * status is bad or has messages come, the wait return. * TODO: can condition_wait support timeout. */ while (!ep->status.shutdown && list_empty (&ep->rcv.head)) { ep->rcv.waiters++; condition_wait (&ep->cond, &ep->lock); ep->rcv.waiters--; } /* Check the endpoint status, maybe it's bad */ if (ep->status.shutdown) { mutex_unlock (&ep->lock); eid_put (eid); ERRNO_RETURN (EBADF); } msgbuf_head_out (&ep->rcv, ubuf); mutex_unlock (&ep->lock); eid_put (eid); return 0; }
static int repep_getopt (struct epbase *ep, int opt, void *optval, int *optlen) { int rc; if (opt < 0 || opt >= NELEM (getopt_vfptr, ep_getopt) || !getopt_vfptr[opt]) { ERRNO_RETURN (EINVAL); } rc = getopt_vfptr[opt] (ep, optval, optlen); return rc; }
static int set_proxyto (struct epbase *ep, void *optval, int optlen) { int rc; int backend_eid = * (int *) optval; struct epbase *peer = eid_get (backend_eid); if (!peer) { ERRNO_RETURN (EBADF); } rc = epbase_proxyto (ep, peer); eid_put (backend_eid); return rc; }
int sp_add (int eid, int fd) { struct epbase *ep = eid_get (eid); int rc; int on = 1; struct tgtd *tg; if (!ep) { ERRNO_RETURN (EBADF); } if ( (tg = ep->vfptr.join (ep, fd) ) ) { if ((rc = epbase_add_tgtd (ep, tg))) { ep->vfptr.term (ep, tg); eid_put (eid); return -1; } } xsetopt (fd, XL_SOCKET, XNOBLOCK, &on, sizeof (on) ); eid_put (eid); return 0; }