diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2005-05-04 03:17:49 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2005-05-04 03:17:49 +0000 |
commit | f7a58a5e405d25b0090afa55543753dbe2c2b50c (patch) | |
tree | d974f482b466d1ca7f9904d46d854c49c2401bb2 /lib/libevent/poll.c | |
parent | 8279b699f940340193b2c9cc385100168b137a19 (diff) |
update to libevent 1.0d; keep local changes
thanks to Alexander von Gernler for testing
and some bug fixes
ok mpf@ norby@
Diffstat (limited to 'lib/libevent/poll.c')
-rw-r--r-- | lib/libevent/poll.c | 101 |
1 files changed, 73 insertions, 28 deletions
diff --git a/lib/libevent/poll.c b/lib/libevent/poll.c index bc3a19006a6..64cedaef71c 100644 --- a/lib/libevent/poll.c +++ b/lib/libevent/poll.c @@ -1,4 +1,4 @@ -/* $OpenBSD: poll.c,v 1.6 2005/04/22 00:56:25 brad Exp $ */ +/* $OpenBSD: poll.c,v 1.7 2005/05/04 03:17:48 brad Exp $ */ /* * Copyright 2000-2003 Niels Provos <provos@citi.umich.edu> @@ -55,8 +55,13 @@ extern volatile sig_atomic_t evsignal_caught; struct pollop { int event_count; /* Highest number alloc */ + int fd_count; /* Size of idxplus1_by_fd */ struct pollfd *event_set; - struct event **event_back; + struct event **event_r_back; + struct event **event_w_back; + int *idxplus1_by_fd; /* Index into event_set by fd; we add 1 so + * that 0 (which is easy to memset) can mean + * "no entry." */ sigset_t evsigmask; }; @@ -108,13 +113,19 @@ poll_recalc(struct event_base *base, void *arg, int max) int poll_dispatch(struct event_base *base, void *arg, struct timeval *tv) { - int res, i, count, sec, nfds; + int res, i, count, fd_count, sec, nfds; struct event *ev; struct pollop *pop = arg; + int *idxplus1_by_fd; count = pop->event_count; + fd_count = pop->fd_count; + idxplus1_by_fd = pop->idxplus1_by_fd; + memset(idxplus1_by_fd, 0, sizeof(int)*fd_count); nfds = 0; + TAILQ_FOREACH(ev, &base->eventqueue, ev_next) { + struct pollfd *pfd = NULL; if (nfds + 1 >= count) { if (count < 32) count = 32; @@ -128,34 +139,61 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv) event_warn("realloc"); return (-1); } - pop->event_back = realloc(pop->event_back, + pop->event_r_back = realloc(pop->event_r_back, + count * sizeof(struct event *)); + pop->event_w_back = realloc(pop->event_w_back, count * sizeof(struct event *)); - if (pop->event_back == NULL) { + if (pop->event_r_back == NULL || + pop->event_w_back == NULL) { event_warn("realloc"); return (-1); } pop->event_count = count; } + if (!(ev->ev_events & (EV_READ|EV_WRITE))) + continue; + if (ev->ev_fd >= fd_count) { + int new_count; + if (fd_count < 32) + new_count = 32; + else + new_count = fd_count * 2; + while (new_count <= ev->ev_fd) + new_count *= 2; + idxplus1_by_fd = pop->idxplus1_by_fd = + realloc(pop->idxplus1_by_fd, new_count*sizeof(int)); + if (idxplus1_by_fd == NULL) { + event_warn("realloc"); + return (-1); + } + memset(pop->idxplus1_by_fd + fd_count, + 0, sizeof(int)*(new_count-fd_count)); + fd_count = pop->fd_count = new_count; + } + i = idxplus1_by_fd[ev->ev_fd] - 1; + if (i >= 0) { + pfd = &pop->event_set[i]; + } else { + i = nfds++; + pfd = &pop->event_set[i]; + pop->event_w_back[i] = pop->event_r_back[i] = NULL; + pfd->events = 0; + idxplus1_by_fd[ev->ev_fd] = i + 1; + } + if (ev->ev_events & EV_WRITE) { - struct pollfd *pfd = &pop->event_set[nfds]; pfd->fd = ev->ev_fd; - pfd->events = POLLOUT; + pfd->events |= POLLOUT; pfd->revents = 0; - pop->event_back[nfds] = ev; - - nfds++; + pop->event_w_back[i] = ev; } if (ev->ev_events & EV_READ) { - struct pollfd *pfd = &pop->event_set[nfds]; - pfd->fd = ev->ev_fd; - pfd->events = POLLIN; + pfd->events |= POLLIN; pfd->revents = 0; - pop->event_back[nfds] = ev; - - nfds++; + pop->event_r_back[i] = ev; } } @@ -185,8 +223,9 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv) return (0); for (i = 0; i < nfds; i++) { - int what = pop->event_set[i].revents; - + int what = pop->event_set[i].revents; + struct event *r_ev = NULL, *w_ev = NULL; + res = 0; /* If the file gets closed notify */ @@ -194,21 +233,27 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv) what |= POLLIN|POLLOUT; if (what & POLLERR) what |= POLLIN|POLLOUT; - if (what & POLLIN) + if (what & POLLIN) { res |= EV_READ; - if (what & POLLOUT) + r_ev = pop->event_r_back[i]; + } + if (what & POLLOUT) { res |= EV_WRITE; + w_ev = pop->event_w_back[i]; + } if (res == 0) continue; - ev = pop->event_back[i]; - res &= ev->ev_events; - - if (res) { - if (!(ev->ev_events & EV_PERSIST)) - event_del(ev); - event_active(ev, res, 1); - } + 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); + } } return (0); |