static void vwk_sess_ev(struct vwk *vwk, const struct kevent *kp, double now) { struct sess *sp; AN(kp->udata); assert(kp->udata != vwk->pipes); CAST_OBJ_NOTNULL(sp, kp->udata, SESS_MAGIC); DSL(DBG_WAITER, sp->vxid, "KQ: sp %p kev data %lu flags 0x%x%s", sp, (unsigned long)kp->data, kp->flags, (kp->flags & EV_EOF) ? " EOF" : ""); if (kp->data > 0) { VTAILQ_REMOVE(&vwk->sesshead, sp, list); SES_Handle(sp, now); return; } else if (kp->flags & EV_EOF) { VTAILQ_REMOVE(&vwk->sesshead, sp, list); SES_Delete(sp, SC_REM_CLOSE, now); return; } else { VSL(SLT_Debug, sp->vxid, "KQ: sp %p kev data %lu flags 0x%x%s", sp, (unsigned long)kp->data, kp->flags, (kp->flags & EV_EOF) ? " EOF" : ""); } }
static void vwk_kev(struct vwk *vwk, const struct kevent *kp) { int i, j; struct sess *sp; struct sess *ss[NKEV]; AN(kp->udata); if (kp->udata == vwk->pipes) { j = 0; i = read(vwk->pipes[0], ss, sizeof ss); if (i == -1 && errno == EAGAIN) return; while (i >= sizeof ss[0]) { CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC); assert(ss[j]->fd >= 0); AZ(ss[j]->obj); VTAILQ_INSERT_TAIL(&vwk->sesshead, ss[j], list); vwk_kq_sess(vwk, ss[j], EV_ADD | EV_ONESHOT); j++; i -= sizeof ss[0]; } assert(i == 0); return; } CAST_OBJ_NOTNULL(sp, kp->udata, SESS_MAGIC); DSL(0x04, SLT_Debug, sp->vsl_id, "KQ: sp %p kev data %lu flags 0x%x%s", sp, (unsigned long)kp->data, kp->flags, (kp->flags & EV_EOF) ? " EOF" : ""); assert((sp->vsl_id & VSL_IDENTMASK) == kp->ident); assert((sp->vsl_id & VSL_IDENTMASK) == sp->fd); if (kp->data > 0) { i = HTC_Rx(sp->htc); if (i == 0) { vwk_kq_sess(vwk, sp, EV_ADD | EV_ONESHOT); return; /* more needed */ } VTAILQ_REMOVE(&vwk->sesshead, sp, list); SES_Handle(sp, i); return; } else if (kp->flags & EV_EOF) { VTAILQ_REMOVE(&vwk->sesshead, sp, list); SES_Delete(sp, "EOF"); return; } else { VSL(SLT_Debug, sp->vsl_id, "KQ: sp %p kev data %lu flags 0x%x%s", sp, (unsigned long)kp->data, kp->flags, (kp->flags & EV_EOF) ? " EOF" : ""); } }
static inline void vws_port_ev(struct vws *vws, port_event_t *ev) { struct sess *sp; if(ev->portev_source == PORT_SOURCE_USER) { CAST_OBJ_NOTNULL(sp, ev->portev_user, SESS_MAGIC); assert(sp->fd >= 0); AZ(sp->obj); VTAILQ_INSERT_TAIL(&vws->sesshead, sp, list); vws_add(vws, sp->fd, sp); } else { int i; assert(ev->portev_source == PORT_SOURCE_FD); CAST_OBJ_NOTNULL(sp, ev->portev_user, SESS_MAGIC); assert(sp->fd >= 0); if(ev->portev_events & POLLERR) { vws_del(vws, sp->fd); VTAILQ_REMOVE(&vws->sesshead, sp, list); SES_Delete(sp, "EOF"); return; } i = HTC_Rx(sp->htc); if (i == 0) { /* incomplete header, wait for more data */ vws_add(vws, sp->fd, sp); return; } /* * note: the original man page for port_associate(3C) states: * * When an event for a PORT_SOURCE_FD object is retrieved, * the object no longer has an association with the port. * * This can be read along the lines of sparing the * port_dissociate after port_getn(), but in fact, * port_dissociate should be used * * Ref: http://opensolaris.org/jive/thread.jspa?threadID=129476&tstart=0 */ vws_del(vws, sp->fd); VTAILQ_REMOVE(&vws->sesshead, sp, list); /* SES_Handle will also handle errors */ SES_Handle(sp, i); } return; }
static void vwe_eev(struct vwe *vwe, const struct epoll_event *ep) { struct sess *ss[NEEV], *sp; int i, j; AN(ep->data.ptr); if (ep->data.ptr == vwe->pipes) { if (ep->events & EPOLLIN || ep->events & EPOLLPRI) { j = 0; i = read(vwe->pipes[0], ss, sizeof ss); if (i == -1 && errno == EAGAIN) return; while (i >= sizeof ss[0]) { CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC); assert(ss[j]->fd >= 0); AZ(ss[j]->obj); VTAILQ_INSERT_TAIL(&vwe->sesshead, ss[j], list); vwe_cond_modadd(vwe, ss[j]->fd, ss[j]); j++; i -= sizeof ss[0]; } assert(i == 0); } } else { CAST_OBJ_NOTNULL(sp, ep->data.ptr, SESS_MAGIC); if (ep->events & EPOLLIN || ep->events & EPOLLPRI) { i = HTC_Rx(sp->htc); if (i == 0) { vwe_modadd(vwe, sp->fd, sp, EPOLL_CTL_MOD); return; /* more needed */ } VTAILQ_REMOVE(&vwe->sesshead, sp, list); SES_Handle(sp, i); } else if (ep->events & EPOLLERR) { VTAILQ_REMOVE(&vwe->sesshead, sp, list); SES_Delete(sp, "ERR"); } else if (ep->events & EPOLLHUP) { VTAILQ_REMOVE(&vwe->sesshead, sp, list); SES_Delete(sp, "HUP"); } else if (ep->events & EPOLLRDHUP) { VTAILQ_REMOVE(&vwe->sesshead, sp, list); SES_Delete(sp, "RHUP"); } } }
static void vwe_eev(struct vwe *vwe, const struct epoll_event *ep, double now) { struct sess *ss[NEEV], *sp; int i, j; AN(ep->data.ptr); if (ep->data.ptr == vwe->pipes) { if (ep->events & EPOLLIN || ep->events & EPOLLPRI) { j = 0; i = read(vwe->pipes[0], ss, sizeof ss); if (i == -1 && errno == EAGAIN) return; while (i >= sizeof ss[0]) { CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC); assert(ss[j]->fd >= 0); VTAILQ_INSERT_TAIL(&vwe->sesshead, ss[j], list); vwe_cond_modadd(vwe, ss[j]->fd, ss[j]); j++; i -= sizeof ss[0]; } assert(i == 0); } } else { CAST_OBJ_NOTNULL(sp, ep->data.ptr, SESS_MAGIC); if (ep->events & EPOLLIN || ep->events & EPOLLPRI) { VTAILQ_REMOVE(&vwe->sesshead, sp, list); SES_Handle(sp, now); } else if (ep->events & EPOLLERR) { VTAILQ_REMOVE(&vwe->sesshead, sp, list); SES_Delete(sp, SC_REM_CLOSE, now); } else if (ep->events & EPOLLHUP) { VTAILQ_REMOVE(&vwe->sesshead, sp, list); SES_Delete(sp, SC_REM_CLOSE, now); } else if (ep->events & EPOLLRDHUP) { VTAILQ_REMOVE(&vwe->sesshead, sp, list); SES_Delete(sp, SC_REM_CLOSE, now); } } }