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; }
int sp_getopt(int eid, int opt, void *optval, int *optlen) { int rc; struct epbase *ep = eid_get(eid); if (!ep) { errno = EBADF; return -1; } rc = ep->vfptr.getopt(ep, opt, optval, optlen); eid_put(eid); 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; }