static int select_del(void *arg, struct event *ev) { struct selectop *sop = arg; check_selectop(sop); if (ev->ev_events & EV_SIGNAL) return (evsignal_del(ev)); if (sop->event_fds < ev->ev_fd) { check_selectop(sop); return (0); } if (ev->ev_events & EV_READ) { FD_CLR(ev->ev_fd, sop->event_readset_in); sop->event_r_by_fd[ev->ev_fd] = NULL; } if (ev->ev_events & EV_WRITE) { FD_CLR(ev->ev_fd, sop->event_writeset_in); sop->event_w_by_fd[ev->ev_fd] = NULL; } check_selectop(sop); return (0); }
static int select_del(void *arg, struct event *ev) { struct selectop *sop = arg; check_selectop(sop); if (ev->ev_events & EV_SIGNAL) // deal with signal event return (evsignal_del(ev)); if (sop->event_fds < ev->ev_fd) { // event_fds is the current exist largest fd, so the removed fd should be not larger than it check_selectop(sop); return (0); } if (ev->ev_events & EV_READ) { // the event is registered for READ FD_CLR(ev->ev_fd, sop->event_readset_in); // remove the fd from select read set sop->event_r_by_fd[ev->ev_fd] = NULL; // remove fd from array } if (ev->ev_events & EV_WRITE) { FD_CLR(ev->ev_fd, sop->event_writeset_in); sop->event_w_by_fd[ev->ev_fd] = NULL; } check_selectop(sop); return (0); }
static int select_resize(struct selectop *sop, int fdsz) { fd_set *readset_in = NULL; fd_set *writeset_in = NULL; if (sop->event_readset_in) check_selectop(sop); if ((readset_in = mm_realloc(sop->event_readset_in, fdsz)) == NULL) goto error; sop->event_readset_in = readset_in; if ((writeset_in = mm_realloc(sop->event_writeset_in, fdsz)) == NULL) goto error; sop->event_writeset_in = writeset_in; sop->resize_out_sets = 1; memset((char *)sop->event_readset_in + sop->event_fdsz, 0, fdsz - sop->event_fdsz); memset((char *)sop->event_writeset_in + sop->event_fdsz, 0, fdsz - sop->event_fdsz); sop->event_fdsz = fdsz; check_selectop(sop); return (0); error: event_warn("malloc"); return (-1); }
static int select_dispatch(struct event_base *base, void *arg, struct timeval *tv) { int res, i, j; struct selectop *sop = arg; check_selectop(sop); memcpy(sop->event_readset_out, sop->event_readset_in, sop->event_fdsz); memcpy(sop->event_writeset_out, sop->event_writeset_in, sop->event_fdsz); res = select(sop->event_fds + 1, sop->event_readset_out, sop->event_writeset_out, NULL, tv); check_selectop(sop); if (res == -1) { if (errno != EINTR) { event_warn("select"); return (-1); } evsignal_process(base); return (0); } else if (base->sig.evsignal_caught) { evsignal_process(base); } event_debug(("%s: select reports %d", __func__, res)); check_selectop(sop); i = arc4random_uniform(sop->event_fds + 1); for (j = 0; j <= sop->event_fds; ++j) { struct event *r_ev = NULL, *w_ev = NULL; if (++i >= sop->event_fds+1) i = 0; res = 0; if (FD_ISSET(i, sop->event_readset_out)) { r_ev = sop->event_r_by_fd[i]; res |= EV_READ; } if (FD_ISSET(i, sop->event_writeset_out)) { w_ev = sop->event_w_by_fd[i]; res |= EV_WRITE; } if (r_ev && (res & r_ev->ev_events)) { event_active(r_ev, res & r_ev->ev_events, 1); } if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) { event_active(w_ev, res & w_ev->ev_events, 1); } } check_selectop(sop); return (0); }
int select_dispatch(struct event_base *base, void *arg, struct timeval *tv) { int res, i; struct selectop *sop = arg; check_selectop(sop); memcpy(sop->event_readset_out, sop->event_readset_in, sop->event_fdsz); memcpy(sop->event_writeset_out, sop->event_writeset_in, sop->event_fdsz); res = select(sop->event_fds + 1, sop->event_readset_out, sop->event_writeset_out, NULL, tv); check_selectop(sop); if (res == -1) { if (errno != EINTR) { event_warn("select"); return (-1); } evsignal_process(); return (0); } else if (evsignal_caught) evsignal_process(); event_debug(("%s: select reports %d", __func__, res)); check_selectop(sop); for (i = 0; i <= sop->event_fds; ++i) { struct event *r_ev = NULL, *w_ev = NULL; res = 0; if (FD_ISSET(i, sop->event_readset_out)) { r_ev = sop->event_r_by_fd[i]; res |= EV_READ; } if (FD_ISSET(i, sop->event_writeset_out)) { w_ev = sop->event_w_by_fd[i]; res |= EV_WRITE; } if (r_ev && (res & r_ev->ev_events)) { if (!(r_ev->ev_events & EV_PERSIST)) event_del(r_ev); event_active(r_ev, res & r_ev->ev_events, 1); } if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) { if (!(w_ev->ev_events & EV_PERSIST)) event_del(w_ev); event_active(w_ev, res & w_ev->ev_events, 1); } } check_selectop(sop); return (0); }
static int select_resize(struct selectop *sop, size_t fdsz) { size_t n_events, n_events_old; fd_set *readset_in = NULL; fd_set *writeset_in = NULL; fd_set *readset_out = NULL; fd_set *writeset_out = NULL; struct event **r_by_fd = NULL; struct event **w_by_fd = NULL; n_events = (fdsz/sizeof(fd_mask)) * NFDBITS; n_events_old = (sop->event_fdsz/sizeof(fd_mask)) * NFDBITS; if (sop->event_readset_in) check_selectop(sop); if ((readset_in = realloc(sop->event_readset_in, fdsz)) == NULL) goto error; sop->event_readset_in = readset_in; if ((readset_out = realloc(sop->event_readset_out, fdsz)) == NULL) goto error; sop->event_readset_out = readset_out; if ((writeset_in = realloc(sop->event_writeset_in, fdsz)) == NULL) goto error; sop->event_writeset_in = writeset_in; if ((writeset_out = realloc(sop->event_writeset_out, fdsz)) == NULL) goto error; sop->event_writeset_out = writeset_out; if ((r_by_fd = reallocarray(sop->event_r_by_fd, n_events, sizeof(struct event *))) == NULL) goto error; sop->event_r_by_fd = r_by_fd; if ((w_by_fd = reallocarray(sop->event_w_by_fd, n_events, sizeof(struct event *))) == NULL) goto error; sop->event_w_by_fd = w_by_fd; memset((char *)sop->event_readset_in + sop->event_fdsz, 0, fdsz - sop->event_fdsz); memset((char *)sop->event_writeset_in + sop->event_fdsz, 0, fdsz - sop->event_fdsz); memset(sop->event_r_by_fd + n_events_old, 0, (n_events-n_events_old) * sizeof(struct event*)); memset(sop->event_w_by_fd + n_events_old, 0, (n_events-n_events_old) * sizeof(struct event*)); sop->event_fdsz = fdsz; check_selectop(sop); return (0); error: event_warn("malloc"); return (-1); }
static int select_add(void *arg, struct event *ev) { struct selectop *sop = arg; if (ev->ev_events & EV_SIGNAL) return (evsignal_add(ev)); check_selectop(sop); /* * Keep track of the highest fd, so that we can calculate the size * of the fd_sets for select(2) */ if (sop->event_fds < ev->ev_fd) { size_t fdsz = sop->event_fdsz; if (fdsz < sizeof(fd_mask)) fdsz = sizeof(fd_mask); while (fdsz < (howmany(ev->ev_fd + 1, NFDBITS) * sizeof(fd_mask))) fdsz *= 2; if (fdsz != sop->event_fdsz) { if (select_resize(sop, fdsz)) { check_selectop(sop); return (-1); } } sop->event_fds = ev->ev_fd; } if (ev->ev_events & EV_READ) { FD_SET(ev->ev_fd, sop->event_readset_in); sop->event_r_by_fd[ev->ev_fd] = ev; } if (ev->ev_events & EV_WRITE) { FD_SET(ev->ev_fd, sop->event_writeset_in); sop->event_w_by_fd[ev->ev_fd] = ev; } check_selectop(sop); return (0); }
int select_recalc(struct event_base *base, void *arg, int max) { struct selectop *sop = arg; check_selectop(sop); return (0); }
static int select_add(struct event_base *base, int fd, short old, short events, void *p) { struct selectop *sop = base->evbase; (void) p; EVUTIL_ASSERT((events & EV_SIGNAL) == 0); check_selectop(sop); /* * Keep track of the highest fd, so that we can calculate the size * of the fd_sets for select(2) */ if (sop->event_fds < fd) { int fdsz = sop->event_fdsz; if (fdsz < (int)sizeof(fd_mask)) fdsz = (int)sizeof(fd_mask); /* In theory we should worry about overflow here. In * reality, though, the highest fd on a unixy system will * not overflow here. XXXX */ while (fdsz < (int) (howmany(fd + 1, NFDBITS) * sizeof(fd_mask))) fdsz *= 2; if (fdsz != sop->event_fdsz) { if (select_resize(sop, fdsz)) { check_selectop(sop); return (-1); } } sop->event_fds = fd; } if (events & EV_READ) FD_SET(fd, sop->event_readset_in); if (events & EV_WRITE) FD_SET(fd, sop->event_writeset_in); check_selectop(sop); return (0); }
static int select_add(struct event_base *base, int fd, short old, short events, void *p) { struct selectop *sop = base->evbase; (void) p; EVUTIL_ASSERT((events & EV_SIGNAL) == 0); check_selectop(sop); /* * Keep track of the highest fd, so that we can calculate the size * of the fd_sets for select(2) */ if (sop->event_fds < fd) { int fdsz = sop->event_fdsz; if (fdsz < sizeof(fd_mask)) fdsz = sizeof(fd_mask); while (fdsz < (howmany(fd + 1, NFDBITS) * sizeof(fd_mask))) fdsz *= 2; if (fdsz != sop->event_fdsz) { if (select_resize(sop, fdsz)) { check_selectop(sop); return (-1); } } sop->event_fds = fd; } if (events & EV_READ) FD_SET(fd, sop->event_readset_in); if (events & EV_WRITE) FD_SET(fd, sop->event_writeset_in); check_selectop(sop); return (0); }
static int select_resize(struct selectop *sop, int fdsz) { fd_set *readset_in = NULL; fd_set *writeset_in = NULL; if (sop->event_readset_in) check_selectop(sop); if ((readset_in = mm_realloc(sop->event_readset_in, fdsz)) == NULL) goto error; sop->event_readset_in = readset_in; if ((writeset_in = mm_realloc(sop->event_writeset_in, fdsz)) == NULL) { /* Note that this will leave event_readset_in expanded. * That's okay; we wouldn't want to free it, since that would * change the semantics of select_resize from "expand the * readset_in and writeset_in, or return -1" to "expand the * *set_in members, or trash them and return -1." */ goto error; } sop->event_writeset_in = writeset_in; sop->resize_out_sets = 1; memset((char *)sop->event_readset_in + sop->event_fdsz, 0, fdsz - sop->event_fdsz); memset((char *)sop->event_writeset_in + sop->event_fdsz, 0, fdsz - sop->event_fdsz); sop->event_fdsz = fdsz; check_selectop(sop); return (0); error: event_warn("malloc"); return (-1); }
static int select_del(struct event_base *base, int fd, short old, short events, void *p) { struct selectop *sop = base->evbase; (void)p; EVUTIL_ASSERT((events & EV_SIGNAL) == 0); check_selectop(sop); if (sop->event_fds < fd) { check_selectop(sop); return (0); } if (events & EV_READ) FD_CLR(fd, sop->event_readset_in); if (events & EV_WRITE) FD_CLR(fd, sop->event_writeset_in); check_selectop(sop); return (0); }
static int select_dispatch(struct event_base *base, struct timeval *tv) { int res=0, i, j, nfds; struct selectop *sop = base->evbase; check_selectop(sop); if (sop->resize_out_sets) { fd_set *readset_out=NULL, *writeset_out=NULL; size_t sz = sop->event_fdsz; if (!(readset_out = mm_realloc(sop->event_readset_out, sz))) return (-1); sop->event_readset_out = readset_out; if (!(writeset_out = mm_realloc(sop->event_writeset_out, sz))) { /* We don't free readset_out here, since it was * already successfully reallocated. The next time * we call select_dispatch, the realloc will be a * no-op. */ return (-1); } sop->event_writeset_out = writeset_out; sop->resize_out_sets = 0; } memcpy(sop->event_readset_out, sop->event_readset_in, sop->event_fdsz); memcpy(sop->event_writeset_out, sop->event_writeset_in, sop->event_fdsz); nfds = sop->event_fds+1; EVBASE_RELEASE_LOCK(base, th_base_lock); res = select(nfds, sop->event_readset_out, sop->event_writeset_out, NULL, tv); EVBASE_ACQUIRE_LOCK(base, th_base_lock); check_selectop(sop); if (res == -1) { if (errno != EINTR) { event_warn("select"); return (-1); } return (0); } event_debug(("%s: select reports %d", __func__, res)); check_selectop(sop); i = random() % nfds; for (j = 0; j < nfds; ++j) { if (++i >= nfds) i = 0; res = 0; if (FD_ISSET(i, sop->event_readset_out)) res |= EV_READ; if (FD_ISSET(i, sop->event_writeset_out)) res |= EV_WRITE; if (res == 0) continue; evmap_io_active(base, i, res); } check_selectop(sop); return (0); }
static int select_dispatch(struct event_base *base, struct timeval *tv) { int res=0, i, j, nfds; struct selectop *sop = base->evbase; check_selectop(sop); if (sop->resize_out_sets) { fd_set *readset_out=NULL, *writeset_out=NULL; size_t sz = sop->event_fdsz; if (!(readset_out = mm_realloc(sop->event_readset_out, sz))) return (-1); if (!(writeset_out = mm_realloc(sop->event_writeset_out, sz))) { mm_free(readset_out); return (-1); } sop->event_readset_out = readset_out; sop->event_writeset_out = writeset_out; sop->resize_out_sets = 0; } memcpy(sop->event_readset_out, sop->event_readset_in, sop->event_fdsz); memcpy(sop->event_writeset_out, sop->event_writeset_in, sop->event_fdsz); nfds = sop->event_fds+1; EVBASE_RELEASE_LOCK(base, th_base_lock); res = select(nfds, sop->event_readset_out, sop->event_writeset_out, NULL, tv); EVBASE_ACQUIRE_LOCK(base, th_base_lock); check_selectop(sop); if (res == -1) { if (errno != EINTR) { event_warn("select"); return (-1); } evsig_process(base); return (0); } else if (base->sig.evsig_caught) { evsig_process(base); } event_debug(("%s: select reports %d", __func__, res)); check_selectop(sop); i = random() % (nfds+1); for (j = 0; j <= nfds; ++j) { if (++i >= nfds+1) i = 0; res = 0; if (FD_ISSET(i, sop->event_readset_out)) res |= EV_READ; if (FD_ISSET(i, sop->event_writeset_out)) res |= EV_WRITE; if (res == 0) continue; evmap_io_active(base, i, res); } check_selectop(sop); return (0); }