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");
		}
	}
}
Example #5
0
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);
		}
	}
}