int kqueue_iod_modify(struct npool *nsp, struct niod *iod, struct nevent *nse, int ev_set, int ev_clr) { struct kevent kev[2]; int new_events, i; struct kqueue_engine_info *kinfo = (struct kqueue_engine_info *)nsp->engine_data; assert((ev_set & ev_clr) == 0); assert(IOD_PROPGET(iod, IOD_REGISTERED)); new_events = iod->watched_events; new_events |= ev_set; new_events &= ~ev_clr; if (new_events == iod->watched_events) return 1; /* nothing to do */ i = 0; if ((ev_set ^ ev_clr) & EV_READ) { EV_SET(&kev[i], nsock_iod_get_sd(iod), EVFILT_READ, EV_SETFLAG(ev_set, EV_READ), 0, 0, (void *)iod); i++; } if ((ev_set ^ ev_clr) & EV_WRITE) { EV_SET(&kev[i], nsock_iod_get_sd(iod), EVFILT_WRITE, EV_SETFLAG(ev_set, EV_WRITE), 0, 0, (void *)iod); i++; } if (i > 0 && kevent(kinfo->kqfd, kev, i, NULL, 0, NULL) < 0) fatal("Unable to update events for IOD #%lu: %s", iod->id, strerror(errno)); iod->watched_events = new_events; return 1; }
int kqueue_iod_register(struct npool *nsp, struct niod *iod, struct nevent *nse, int ev) { struct kqueue_engine_info *kinfo = (struct kqueue_engine_info *)nsp->engine_data; assert(!IOD_PROPGET(iod, IOD_REGISTERED)); IOD_PROPSET(iod, IOD_REGISTERED); iod->watched_events = EV_NONE; kqueue_iod_modify(nsp, iod, nse, ev, EV_NONE); if (nsock_iod_get_sd(iod) > kinfo->maxfd) kinfo->maxfd = nsock_iod_get_sd(iod); return 1; }
int epoll_iod_register(struct npool *nsp, struct niod *iod, int ev) { int sd; struct epoll_event epev; struct epoll_engine_info *einfo = (struct epoll_engine_info *)nsp->engine_data; assert(!IOD_PROPGET(iod, IOD_REGISTERED)); iod->watched_events = ev; memset(&epev, 0x00, sizeof(struct epoll_event)); epev.events = EPOLLET; epev.data.ptr = (void *)iod; if (ev & EV_READ) epev.events |= EPOLL_R_FLAGS; if (ev & EV_WRITE) epev.events |= EPOLL_W_FLAGS; if (ev & EV_EXCEPT) epev.events |= EPOLL_X_FLAGS; sd = nsock_iod_get_sd(iod); if (epoll_ctl(einfo->epfd, EPOLL_CTL_ADD, sd, &epev) < 0) fatal("Unable to register IOD #%lu: %s", iod->id, strerror(errno)); IOD_PROPSET(iod, IOD_REGISTERED); return 1; }
int poll_iod_modify(struct npool *nsp, struct niod *iod, struct nevent *nse, int ev_set, int ev_clr) { int sd; int new_events; struct poll_engine_info *pinfo = (struct poll_engine_info *)nsp->engine_data; assert((ev_set & ev_clr) == 0); assert(IOD_PROPGET(iod, IOD_REGISTERED)); new_events = iod->watched_events; new_events |= ev_set; new_events &= ~ev_clr; if (new_events == iod->watched_events) return 1; /* nothing to do */ iod->watched_events = new_events; sd = nsock_iod_get_sd(iod); pinfo->events[sd].fd = sd; pinfo->events[sd].events = 0; /* regenerate the current set of events for this IOD */ if (iod->watched_events & EV_READ) pinfo->events[sd].events |= POLL_R_FLAGS; if (iod->watched_events & EV_WRITE) pinfo->events[sd].events |= POLL_W_FLAGS; #ifndef WIN32 if (iod->watched_events & EV_EXCEPT) pinfo->events[sd].events |= POLL_X_FLAGS; #endif return 1; }
int poll_iod_register(struct npool *nsp, struct niod *iod, struct nevent *nse, int ev) { struct poll_engine_info *pinfo = (struct poll_engine_info *)nsp->engine_data; int sd; assert(!IOD_PROPGET(iod, IOD_REGISTERED)); iod->watched_events = ev; sd = nsock_iod_get_sd(iod); while (pinfo->capacity < sd + 1) evlist_grow(pinfo); pinfo->events[sd].fd = sd; pinfo->events[sd].events = 0; pinfo->events[sd].revents = 0; pinfo->max_fd = MAX(pinfo->max_fd, sd); if (ev & EV_READ) pinfo->events[sd].events |= POLL_R_FLAGS; if (ev & EV_WRITE) pinfo->events[sd].events |= POLL_W_FLAGS; #ifndef WIN32 if (ev & EV_EXCEPT) pinfo->events[sd].events |= POLL_X_FLAGS; #endif IOD_PROPSET(iod, IOD_REGISTERED); return 1; }
int kqueue_iod_unregister(struct npool *nsp, struct niod *iod) { struct kqueue_engine_info *kinfo = (struct kqueue_engine_info *)nsp->engine_data; /* some IODs can be unregistered here if they're associated to an event that was * immediately completed */ if (IOD_PROPGET(iod, IOD_REGISTERED)) { kqueue_iod_modify(nsp, iod, NULL, EV_NONE, EV_READ|EV_WRITE); IOD_PROPCLR(iod, IOD_REGISTERED); if (nsock_iod_get_sd(iod) == kinfo->maxfd) kinfo->maxfd--; } iod->watched_events = EV_NONE; return 1; }
int epoll_iod_unregister(struct npool *nsp, struct niod *iod) { iod->watched_events = EV_NONE; /* some IODs can be unregistered here if they're associated to an event that was * immediately completed */ if (IOD_PROPGET(iod, IOD_REGISTERED)) { struct epoll_engine_info *einfo = (struct epoll_engine_info *)nsp->engine_data; int sd; sd = nsock_iod_get_sd(iod); epoll_ctl(einfo->epfd, EPOLL_CTL_DEL, sd, NULL); IOD_PROPCLR(iod, IOD_REGISTERED); } return 1; }
int poll_iod_unregister(struct npool *nsp, struct niod *iod) { iod->watched_events = EV_NONE; /* some IODs can be unregistered here if they're associated to an event that was * immediately completed */ if (IOD_PROPGET(iod, IOD_REGISTERED)) { struct poll_engine_info *pinfo = (struct poll_engine_info *)nsp->engine_data; int sd; sd = nsock_iod_get_sd(iod); pinfo->events[sd].fd = -1; pinfo->events[sd].events = 0; pinfo->events[sd].revents = 0; if (pinfo->max_fd == sd) lower_max_fd(pinfo); IOD_PROPCLR(iod, IOD_REGISTERED); } return 1; }
int epoll_iod_modify(struct npool *nsp, struct niod *iod, int ev_set, int ev_clr) { int sd; struct epoll_event epev; int new_events; struct epoll_engine_info *einfo = (struct epoll_engine_info *)nsp->engine_data; assert((ev_set & ev_clr) == 0); assert(IOD_PROPGET(iod, IOD_REGISTERED)); memset(&epev, 0x00, sizeof(struct epoll_event)); epev.events = EPOLLET; epev.data.ptr = (void *)iod; new_events = iod->watched_events; new_events |= ev_set; new_events &= ~ev_clr; if (new_events == iod->watched_events) return 1; /* nothing to do */ iod->watched_events = new_events; /* regenerate the current set of events for this IOD */ if (iod->watched_events & EV_READ) epev.events |= EPOLL_R_FLAGS; if (iod->watched_events & EV_WRITE) epev.events |= EPOLL_W_FLAGS; if (iod->watched_events & EV_EXCEPT) epev.events |= EPOLL_X_FLAGS; sd = nsock_iod_get_sd(iod); if (epoll_ctl(einfo->epfd, EPOLL_CTL_MOD, sd, &epev) < 0) fatal("Unable to update events for IOD #%lu: %s", iod->id, strerror(errno)); return 1; }