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); }
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); }
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); }
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); }