/* Iterate through all the event lists (such as connect_events, read_events, * timer_events, etc) and take action for those that have completed (due to * timeout, i/o, etc) */ void iterate_through_event_lists(mspool *nsp, int evcount) { int n; struct kqueue_engine_info *kinfo = (struct kqueue_engine_info *)nsp->engine_data; msiod *nsi; for (n = 0; n < evcount; n++) { struct kevent *kev = &kinfo->events[n]; nsi = (msiod *)kev->udata; /* process all the pending events for this IOD */ process_iod_events(nsp, nsi, get_evmask(nsi, kev)); IOD_PROPSET(nsi, IOD_PROCESSED); } for (n = 0; n < evcount; n++) { struct kevent *kev = &kinfo->events[n]; nsi = (msiod *)kev->udata; if (nsi->state == NSIOD_STATE_DELETED) { if (IOD_PROPGET(nsi, IOD_PROCESSED)) { IOD_PROPCLR(nsi, IOD_PROCESSED); gh_list_remove(&nsp->active_iods, &nsi->nodeq); gh_list_prepend(&nsp->free_iods, &nsi->nodeq); } } } /* iterate through timers and expired events */ process_expired_events(nsp); }
int poll_iod_register(struct npool *nsp, struct niod *iod, 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 = nsi_getsd(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 epoll_iod_register(mspool *nsp, msiod *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 = nsi_getsd(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 select_iod_register(mspool *nsp, msiod *iod, int ev) { assert(!IOD_PROPGET(iod, IOD_REGISTERED)); iod->watched_events = ev; select_iod_modify(nsp, iod, ev, EV_NONE); IOD_PROPSET(iod, IOD_REGISTERED); return 1; }
/* Iterate through all the event lists (such as connect_events, read_events, * timer_events, etc) and take action for those that have completed (due to * timeout, i/o, etc) */ void iterate_through_event_lists(mspool *nsp, int evcount) { int n; struct kqueue_engine_info *kinfo = (struct kqueue_engine_info *)nsp->engine_data; gh_list_elem *current, *next, *last, *timer_last; msevent *nse; msiod *nsi; /* Clear it -- We will find the next event as we go through the list */ nsp->next_ev.tv_sec = 0; last = GH_LIST_LAST_ELEM(&nsp->active_iods); timer_last = GH_LIST_LAST_ELEM(&nsp->timer_events); for (n = 0; n < evcount; n++) { struct kevent *kev = &kinfo->events[n]; nsi = (msiod *)kev->udata; /* process all the pending events for this IOD */ process_iod_events(nsp, nsi, get_evmask(nsi, kev)); IOD_PROPSET(nsi, IOD_PROCESSED); } current = GH_LIST_FIRST_ELEM(&nsp->active_iods); /* cull timeouts amongst the non active IODs */ while (current != NULL && GH_LIST_ELEM_PREV(current) != last) { msiod *nsi = (msiod *)GH_LIST_ELEM_DATA(current); if (IOD_PROPGET(nsi, IOD_PROCESSED)) IOD_PROPCLR(nsi, IOD_PROCESSED); else if (nsi->state != NSIOD_STATE_DELETED && nsi->events_pending) process_iod_events(nsp, nsi, EV_NONE); next = GH_LIST_ELEM_NEXT(current); if (nsi->state == NSIOD_STATE_DELETED) { gh_list_remove_elem(&nsp->active_iods, current); gh_list_prepend(&nsp->free_iods, nsi); } current = next; } /* iterate through timers */ for (current = GH_LIST_FIRST_ELEM(&nsp->timer_events); current != NULL && GH_LIST_ELEM_PREV(current) != timer_last; current = next) { nse = (msevent *)GH_LIST_ELEM_DATA(current); process_event(nsp, &nsp->timer_events, nse, EV_NONE); next = GH_LIST_ELEM_NEXT(current); if (nse->event_done) gh_list_remove_elem(&nsp->timer_events, current); } }
int kqueue_iod_register(mspool *nsp, msiod *iod, 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, ev, EV_NONE); if (nsi_getsd(iod) > kinfo->maxfd) kinfo->maxfd = nsi_getsd(iod); return 1; }