Exemplo n.º 1
0
static int
devpoll_del(void *arg, struct event *ev)
{
	struct devpollop *devpollop = arg;
	struct evdevpoll *evdp;
	int fd, events;
	int needwritedelete = 1, needreaddelete = 1;

	if (ev->ev_events & OPAL_EV_SIGNAL)
		return (evsignal_del(ev));

	fd = ev->ev_fd;
	if (fd >= devpollop->nfds)
		return (0);
	evdp = &devpollop->fds[fd];

	events = 0;
	if (ev->ev_events & OPAL_EV_READ)
		events |= POLLIN;
	if (ev->ev_events & OPAL_EV_WRITE)
		events |= POLLOUT;

	/*
	 * The only way to remove an fd from the /dev/poll monitored set is
	 * to use POLLREMOVE by itself.  This removes ALL events for the fd 
	 * provided so if we care about two events and are only removing one 
	 * we must re-add the other event after POLLREMOVE.
	 */

	if (devpoll_queue(devpollop, fd, POLLREMOVE) != 0)
		return(-1);

	if ((events & (POLLIN|POLLOUT)) != (POLLIN|POLLOUT)) {
		/*
		 * We're not deleting all events, so we must resubmit the
		 * event that we are still interested in if one exists.
		 */

		if ((events & POLLIN) && evdp->evwrite != NULL) {
			/* Deleting read, still care about write */
			devpoll_queue(devpollop, fd, POLLOUT);
			needwritedelete = 0;
		} else if ((events & POLLOUT) && evdp->evread != NULL) {
			/* Deleting write, still care about read */
			devpoll_queue(devpollop, fd, POLLIN);
			needreaddelete = 0;
		}
	}

	if (needreaddelete)
		evdp->evread = NULL;
	if (needwritedelete)
		evdp->evwrite = NULL;

	return (0);
}
Exemplo n.º 2
0
static int
devpoll_add(struct event_base *base, int fd, short old, short events, void *p)
{
	struct devpollop *devpollop = base->evbase;
	int res;
	(void)p;

	/*
	 * It's not necessary to OR the existing read/write events that we
	 * are currently interested in with the new event we are adding.
	 * The /dev/poll driver ORs any new events with the existing events
	 * that it has cached for the fd.
	 */

	res = 0;
	if (events & EV_READ)
		res |= POLLIN;
	if (events & EV_WRITE)
		res |= POLLOUT;

	if (devpoll_queue(devpollop, fd, res) != 0)
		return(-1);

	return (0);
}
Exemplo n.º 3
0
static int
devpoll_add(void *arg, struct event *ev)
{
	struct devpollop *devpollop = arg;
	struct evdevpoll *evdp;
	int fd, events;

	if (ev->ev_events & OPAL_EV_SIGNAL)
		return (evsignal_add(ev));

	fd = ev->ev_fd;
	if (fd >= devpollop->nfds) {
		/* Extend the file descriptor array as necessary */
		if (devpoll_recalc(ev->ev_base, devpollop, fd) == -1)
			return (-1);
	}
	evdp = &devpollop->fds[fd];

	/* 
	 * It's not necessary to OR the existing read/write events that we
	 * are currently interested in with the new event we are adding.
	 * The /dev/poll driver ORs any new events with the existing events
	 * that it has cached for the fd.
	 */

	events = 0;
	if (ev->ev_events & OPAL_EV_READ) {
		if (evdp->evread && evdp->evread != ev) {
		   /* There is already a different read event registered */
		   return(-1);
		}
		events |= POLLIN;
	}

	if (ev->ev_events & OPAL_EV_WRITE) {
		if (evdp->evwrite && evdp->evwrite != ev) {
		   /* There is already a different write event registered */
		   return(-1);
		}
		events |= POLLOUT;
	}

	if (devpoll_queue(devpollop, fd, events) != 0)
		return(-1);

	/* Update events responsible */
	if (ev->ev_events & OPAL_EV_READ)
		evdp->evread = ev;
	if (ev->ev_events & OPAL_EV_WRITE)
		evdp->evwrite = ev;

	return (0);
}
Exemplo n.º 4
0
static int
devpoll_del(struct event_base *base, int fd, short old, short events, void *p)
{
	struct devpollop *devpollop = base->evbase;
	int res;
	(void)p;

	res = 0;
	if (events & EV_READ)
		res |= POLLIN;
	if (events & EV_WRITE)
		res |= POLLOUT;

	/*
	 * The only way to remove an fd from the /dev/poll monitored set is
	 * to use POLLREMOVE by itself.  This removes ALL events for the fd
	 * provided so if we care about two events and are only removing one
	 * we must re-add the other event after POLLREMOVE.
	 */

	if (devpoll_queue(devpollop, fd, POLLREMOVE) != 0)
		return(-1);

	if ((res & (POLLIN|POLLOUT)) != (POLLIN|POLLOUT)) {
		/*
		 * We're not deleting all events, so we must resubmit the
		 * event that we are still interested in if one exists.
		 */

		if ((res & POLLIN) && (old & EV_WRITE)) {
			/* Deleting read, still care about write */
			devpoll_queue(devpollop, fd, POLLOUT);
		} else if ((res & POLLOUT) && (old & EV_READ)) {
			/* Deleting write, still care about read */
			devpoll_queue(devpollop, fd, POLLIN);
		}
	}

	return (0);
}