diff --git a/ChangeLog b/ChangeLog index 46afa167..afe50078 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ Changes in 1.4.12-stable: o Try to contain degree of failure when running on a win32 version so heavily firewalled that we can't fake a socketpair. o Fix an obscure timing-dependent, allocator-dependent crash in the evdns code. o Use __VA_ARGS__ syntax for varargs macros in event_rpcgen when compiler is not GCC. + o Activate fd events in a pseudorandom order with O(N) backends, so that we don't systematically favor low fds (select) or earlier-added fds (poll, win32). o Fix another pair of fencepost bugs in epoll.c. [Patch from Adam Langley.] Changes in 1.4.11-stable: @@ -86,7 +87,6 @@ Changes in 1.4.4-stable: o Fix autoconf script behavior on IRIX. o Make sure winsock2.h include always comes before windows.h include. - Changes in 1.4.3-stable: o include Content-Length in reply for HTTP/1.0 requests with keep-alive o Patch from Tani Hosokawa: make some functions in http.c threadsafe. diff --git a/WIN32-Code/win32.c b/WIN32-Code/win32.c index 213af37a..0d4705fd 100644 --- a/WIN32-Code/win32.c +++ b/WIN32-Code/win32.c @@ -352,8 +352,9 @@ win32_dispatch(struct event_base *base, void *op, { struct win32op *win32op = op; int res = 0; - unsigned i; + unsigned j, i; int fd_count; + SOCKET s; fd_set_copy(win32op->readset_out, win32op->readset_in); fd_set_copy(win32op->exset_out, win32op->readset_in); @@ -384,29 +385,37 @@ win32_dispatch(struct event_base *base, void *op, evsignal_process(base); } - for (i=0; ireadset_out->fd_count; ++i) { - struct event_entry *ent; - SOCKET s = win32op->readset_out->fd_array[i]; - if ((ent = get_event_entry(win32op, s, 0)) && ent->read_event) - event_active(ent->read_event, EV_READ, 1); + if (win32op->readset_out->fd_count) { + i = rand() % win32op->readset_out->fd_count; + for (j=0; jreadset_out->fd_count; ++j) { + if (++i >= win32op->readset_out->fd_count) + i = 0; + s = win32op->readset_out->fd_array[i]; + if ((ent = get_event_entry(win32op, s, 0)) && ent->read_event) + event_active(ent->read_event, EV_READ, 1); + } } - for (i=0; iexset_out->fd_count; ++i) { - struct event_entry *ent; - SOCKET s = win32op->exset_out->fd_array[i]; - if ((ent = get_event_entry(win32op, s, 0)) && ent->read_event) - event_active(ent->read_event, EV_READ, 1); - } - for (i=0; iwriteset_out->fd_count; ++i) { - struct event_entry *ent; - SOCKET s = win32op->writeset_out->fd_array[i]; - if ((ent = get_event_entry(win32op, s, 0)) && ent->write_event) - event_active(ent->write_event, EV_WRITE, 1); + if (win32op->exset_out->fd_count) { + i = rand() % win32op->exset_out->fd_count; + for (j=0; jexset_out->fd_count; ++j) { + if (++i >= win32op-exset_out->fd_count) + i = 0; + s = win32op->exset_out->fd_array[i]; + if ((ent = get_event_entry(win32op, s, 0)) && ent->read_event) + event_active(ent->read_event, EV_READ, 1); + } } + if (win32op->writeset_out->fd_count) { + i = rand() % win32op->writeset_out->fd_count; + for (j=0; jwriteset_out->fd_count; ++j) { + if (++i >= win32op-exset_out->fd_count) + i = 0; + s = win32op->writeset_out->fd_array[i]; + if ((ent = get_event_entry(win32op, s, 0)) && ent->write_event) + event_active(ent->write_event, EV_WRITE, 1); -#if 0 - if (signal_recalc() == -1) - return (-1); -#endif + } + } return (0); } diff --git a/poll.c b/poll.c index b67c6ffa..5d496618 100644 --- a/poll.c +++ b/poll.c @@ -135,7 +135,7 @@ poll_check_ok(struct pollop *pop) static int poll_dispatch(struct event_base *base, void *arg, struct timeval *tv) { - int res, i, msec = -1, nfds; + int res, i, j, msec = -1, nfds; struct pollop *pop = arg; poll_check_ok(pop); @@ -160,12 +160,17 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv) event_debug(("%s: poll reports %d", __func__, res)); - if (res == 0) + if (res == 0 || nfds == 0) return (0); - for (i = 0; i < nfds; i++) { - int what = pop->event_set[i].revents; + i = random() % nfds; + for (j = 0; j < nfds; j++) { struct event *r_ev = NULL, *w_ev = NULL; + int what; + if (++i == nfds) + i = 0; + what = pop->event_set[i].revents; + if (!what) continue; diff --git a/select.c b/select.c index 7faafe4e..ca6639fd 100644 --- a/select.c +++ b/select.c @@ -137,7 +137,7 @@ check_selectop(struct selectop *sop) static int select_dispatch(struct event_base *base, void *arg, struct timeval *tv) { - int res, i; + int res, i, j; struct selectop *sop = arg; check_selectop(sop); @@ -167,8 +167,12 @@ select_dispatch(struct event_base *base, void *arg, struct timeval *tv) event_debug(("%s: select reports %d", __func__, res)); check_selectop(sop); - for (i = 0; i <= sop->event_fds; ++i) { + i = random() % (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];