mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-12 05:48:51 -04:00
Activate fd events in a pseudorandom order on older backends.
New backends like poll and kqueue and so on add fds to the queue in the order that they are triggered. But the select backend currently activates low-numbered fds first, whereas the poll and win32 backends currently favor whatever fds have been on for the longest. This is no good for fairness. svn:r1327
This commit is contained in:
parent
b0d88e680b
commit
b99254ac22
@ -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.
|
||||
|
@ -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; i<win32op->readset_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; j<win32op->readset_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; i<win32op->exset_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; i<win32op->writeset_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; j<win32op->exset_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; j<win32op->writeset_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);
|
||||
}
|
||||
|
13
poll.c
13
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;
|
||||
|
||||
|
8
select.c
8
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];
|
||||
|
Loading…
x
Reference in New Issue
Block a user