diff options
author | Josh Gao <jmgao@google.com> | 2017-08-10 12:30:25 -0700 |
---|---|---|
committer | Josh Gao <jmgao@google.com> | 2017-08-10 12:30:47 -0700 |
commit | 83a0c9c65a60a92d3ea5542596b3ba56db492c37 (patch) | |
tree | 64bb0c050c4db9ad9d721e05e3e199bfd02e60b0 /evmap.c | |
parent | af241a5c8c2cde0fab7d7d563276c1095b00e3b4 (diff) | |
download | libevent-83a0c9c65a60a92d3ea5542596b3ba56db492c37.tar.gz |
Revert "Upgrade to 2.1.8-stable (2017-01-22)." and "Probably Mac build fix?"android-o-iot-preview-5o-iot-preview-5
This reverts commits 2a572d125a91a4aafd3ad8ce87259fc640fa0763 and
af241a5c8c2cde0fab7d7d563276c1095b00e3b4, which break tombstoned.
Bug: http://b/64543673
Test: manual + treehugger
Diffstat (limited to 'evmap.c')
-rw-r--r-- | evmap.c | 548 |
1 files changed, 146 insertions, 402 deletions
@@ -24,22 +24,21 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "event2/event-config.h" -#include "evconfig-private.h" -#ifdef _WIN32 +#ifdef WIN32 #include <winsock2.h> #define WIN32_LEAN_AND_MEAN #include <windows.h> #undef WIN32_LEAN_AND_MEAN #endif #include <sys/types.h> -#if !defined(_WIN32) && defined(EVENT__HAVE_SYS_TIME_H) +#if !defined(WIN32) && defined(_EVENT_HAVE_SYS_TIME_H) #include <sys/time.h> #endif #include <sys/queue.h> #include <stdio.h> #include <stdlib.h> -#ifndef _WIN32 +#ifndef WIN32 #include <unistd.h> #endif #include <errno.h> @@ -56,16 +55,15 @@ write on a given fd, and the number of each. */ struct evmap_io { - struct event_dlist events; + struct event_list events; ev_uint16_t nread; ev_uint16_t nwrite; - ev_uint16_t nclose; }; /* An entry for an evmap_signal list: notes all the events that want to know when a signal triggers. */ struct evmap_signal { - struct event_dlist events; + struct event_list events; }; /* On some platforms, fds start at 0 and increment by 1 as they are @@ -112,38 +110,38 @@ HT_GENERATE(event_io_map, event_map_entry, map_node, hashsocket, eqsocket, #define GET_IO_SLOT(x, map, slot, type) \ do { \ - struct event_map_entry key_, *ent_; \ - key_.fd = slot; \ - ent_ = HT_FIND(event_io_map, map, &key_); \ - (x) = ent_ ? &ent_->ent.type : NULL; \ + struct event_map_entry _key, *_ent; \ + _key.fd = slot; \ + _ent = HT_FIND(event_io_map, map, &_key); \ + (x) = _ent ? &_ent->ent.type : NULL; \ } while (0); #define GET_IO_SLOT_AND_CTOR(x, map, slot, type, ctor, fdinfo_len) \ do { \ - struct event_map_entry key_, *ent_; \ - key_.fd = slot; \ - HT_FIND_OR_INSERT_(event_io_map, map_node, hashsocket, map, \ - event_map_entry, &key_, ptr, \ + struct event_map_entry _key, *_ent; \ + _key.fd = slot; \ + _HT_FIND_OR_INSERT(event_io_map, map_node, hashsocket, map, \ + event_map_entry, &_key, ptr, \ { \ - ent_ = *ptr; \ + _ent = *ptr; \ }, \ { \ - ent_ = mm_calloc(1,sizeof(struct event_map_entry)+fdinfo_len); \ - if (EVUTIL_UNLIKELY(ent_ == NULL)) \ + _ent = mm_calloc(1,sizeof(struct event_map_entry)+fdinfo_len); \ + if (EVUTIL_UNLIKELY(_ent == NULL)) \ return (-1); \ - ent_->fd = slot; \ - (ctor)(&ent_->ent.type); \ - HT_FOI_INSERT_(map_node, map, &key_, ent_, ptr) \ + _ent->fd = slot; \ + (ctor)(&_ent->ent.type); \ + _HT_FOI_INSERT(map_node, map, &_key, _ent, ptr) \ }); \ - (x) = &ent_->ent.type; \ + (x) = &_ent->ent.type; \ } while (0) -void evmap_io_initmap_(struct event_io_map *ctx) +void evmap_io_initmap(struct event_io_map *ctx) { HT_INIT(event_io_map, ctx); } -void evmap_io_clear_(struct event_io_map *ctx) +void evmap_io_clear(struct event_io_map *ctx) { struct event_map_entry **ent, **next, *this; for (ent = HT_START(event_io_map, ctx); ent; ent = next) { @@ -185,14 +183,14 @@ void evmap_io_clear_(struct event_io_map *ctx) GET_SIGNAL_SLOT_AND_CTOR(x,map,slot,type,ctor,fdinfo_len) #define FDINFO_OFFSET sizeof(struct evmap_io) void -evmap_io_initmap_(struct event_io_map* ctx) +evmap_io_initmap(struct event_io_map* ctx) { - evmap_signal_initmap_(ctx); + evmap_signal_initmap(ctx); } void -evmap_io_clear_(struct event_io_map* ctx) +evmap_io_clear(struct event_io_map* ctx) { - evmap_signal_clear_(ctx); + evmap_signal_clear(ctx); } #endif @@ -225,14 +223,14 @@ evmap_make_space(struct event_signal_map *map, int slot, int msize) } void -evmap_signal_initmap_(struct event_signal_map *ctx) +evmap_signal_initmap(struct event_signal_map *ctx) { ctx->nentries = 0; ctx->entries = NULL; } void -evmap_signal_clear_(struct event_signal_map *ctx) +evmap_signal_clear(struct event_signal_map *ctx) { if (ctx->entries != NULL) { int i; @@ -253,22 +251,21 @@ evmap_signal_clear_(struct event_signal_map *ctx) static void evmap_io_init(struct evmap_io *entry) { - LIST_INIT(&entry->events); + TAILQ_INIT(&entry->events); entry->nread = 0; entry->nwrite = 0; - entry->nclose = 0; } /* return -1 on error, 0 on success if nothing changed in the event backend, * and 1 on success if something did. */ int -evmap_io_add_(struct event_base *base, evutil_socket_t fd, struct event *ev) +evmap_io_add(struct event_base *base, evutil_socket_t fd, struct event *ev) { const struct eventop *evsel = base->evsel; struct event_io_map *io = &base->io; struct evmap_io *ctx = NULL; - int nread, nwrite, nclose, retval = 0; + int nread, nwrite, retval = 0; short res = 0, old = 0; struct event *old_ev; @@ -288,14 +285,11 @@ evmap_io_add_(struct event_base *base, evutil_socket_t fd, struct event *ev) nread = ctx->nread; nwrite = ctx->nwrite; - nclose = ctx->nclose; if (nread) old |= EV_READ; if (nwrite) old |= EV_WRITE; - if (nclose) - old |= EV_CLOSED; if (ev->ev_events & EV_READ) { if (++nread == 1) @@ -305,17 +299,13 @@ evmap_io_add_(struct event_base *base, evutil_socket_t fd, struct event *ev) if (++nwrite == 1) res |= EV_WRITE; } - if (ev->ev_events & EV_CLOSED) { - if (++nclose == 1) - res |= EV_CLOSED; - } - if (EVUTIL_UNLIKELY(nread > 0xffff || nwrite > 0xffff || nclose > 0xffff)) { + if (EVUTIL_UNLIKELY(nread > 0xffff || nwrite > 0xffff)) { event_warnx("Too many events reading or writing on fd %d", (int)fd); return -1; } if (EVENT_DEBUG_MODE_IS_ON() && - (old_ev = LIST_FIRST(&ctx->events)) && + (old_ev = TAILQ_FIRST(&ctx->events)) && (old_ev->ev_events&EV_ET) != (ev->ev_events&EV_ET)) { event_warnx("Tried to mix edge-triggered and non-edge-triggered" " events on fd %d", (int)fd); @@ -335,8 +325,7 @@ evmap_io_add_(struct event_base *base, evutil_socket_t fd, struct event *ev) ctx->nread = (ev_uint16_t) nread; ctx->nwrite = (ev_uint16_t) nwrite; - ctx->nclose = (ev_uint16_t) nclose; - LIST_INSERT_HEAD(&ctx->events, ev, ev_io_next); + TAILQ_INSERT_TAIL(&ctx->events, ev, ev_io_next); return (retval); } @@ -344,12 +333,12 @@ evmap_io_add_(struct event_base *base, evutil_socket_t fd, struct event *ev) /* return -1 on error, 0 on success if nothing changed in the event backend, * and 1 on success if something did. */ int -evmap_io_del_(struct event_base *base, evutil_socket_t fd, struct event *ev) +evmap_io_del(struct event_base *base, evutil_socket_t fd, struct event *ev) { const struct eventop *evsel = base->evsel; struct event_io_map *io = &base->io; struct evmap_io *ctx; - int nread, nwrite, nclose, retval = 0; + int nread, nwrite, retval = 0; short res = 0, old = 0; if (fd < 0) @@ -366,14 +355,11 @@ evmap_io_del_(struct event_base *base, evutil_socket_t fd, struct event *ev) nread = ctx->nread; nwrite = ctx->nwrite; - nclose = ctx->nclose; if (nread) old |= EV_READ; if (nwrite) old |= EV_WRITE; - if (nclose) - old |= EV_CLOSED; if (ev->ev_events & EV_READ) { if (--nread == 0) @@ -385,47 +371,37 @@ evmap_io_del_(struct event_base *base, evutil_socket_t fd, struct event *ev) res |= EV_WRITE; EVUTIL_ASSERT(nwrite >= 0); } - if (ev->ev_events & EV_CLOSED) { - if (--nclose == 0) - res |= EV_CLOSED; - EVUTIL_ASSERT(nclose >= 0); - } if (res) { void *extra = ((char*)ctx) + sizeof(struct evmap_io); - if (evsel->del(base, ev->ev_fd, old, res, extra) == -1) { - retval = -1; - } else { - retval = 1; - } + if (evsel->del(base, ev->ev_fd, old, res, extra) == -1) + return (-1); + retval = 1; } ctx->nread = nread; ctx->nwrite = nwrite; - ctx->nclose = nclose; - LIST_REMOVE(ev, ev_io_next); + TAILQ_REMOVE(&ctx->events, ev, ev_io_next); return (retval); } void -evmap_io_active_(struct event_base *base, evutil_socket_t fd, short events) +evmap_io_active(struct event_base *base, evutil_socket_t fd, short events) { struct event_io_map *io = &base->io; struct evmap_io *ctx; struct event *ev; #ifndef EVMAP_USE_HT - if (fd < 0 || fd >= io->nentries) - return; + EVUTIL_ASSERT(fd < io->nentries); #endif GET_IO_SLOT(ctx, io, fd, evmap_io); - if (NULL == ctx) - return; - LIST_FOREACH(ev, &ctx->events, ev_io_next) { + EVUTIL_ASSERT(ctx); + TAILQ_FOREACH(ev, &ctx->events, ev_io_next) { if (ev->ev_events & events) - event_active_nolock_(ev, ev->ev_events & events, 1); + event_active_nolock(ev, ev->ev_events & events, 1); } } @@ -434,12 +410,12 @@ evmap_io_active_(struct event_base *base, evutil_socket_t fd, short events) static void evmap_signal_init(struct evmap_signal *entry) { - LIST_INIT(&entry->events); + TAILQ_INIT(&entry->events); } int -evmap_signal_add_(struct event_base *base, int sig, struct event *ev) +evmap_signal_add(struct event_base *base, int sig, struct event *ev) { const struct eventop *evsel = base->evsigsel; struct event_signal_map *map = &base->sigmap; @@ -453,19 +429,19 @@ evmap_signal_add_(struct event_base *base, int sig, struct event *ev) GET_SIGNAL_SLOT_AND_CTOR(ctx, map, sig, evmap_signal, evmap_signal_init, base->evsigsel->fdinfo_len); - if (LIST_EMPTY(&ctx->events)) { + if (TAILQ_EMPTY(&ctx->events)) { if (evsel->add(base, ev->ev_fd, 0, EV_SIGNAL, NULL) == -1) return (-1); } - LIST_INSERT_HEAD(&ctx->events, ev, ev_signal_next); + TAILQ_INSERT_TAIL(&ctx->events, ev, ev_signal_next); return (1); } int -evmap_signal_del_(struct event_base *base, int sig, struct event *ev) +evmap_signal_del(struct event_base *base, int sig, struct event *ev) { const struct eventop *evsel = base->evsigsel; struct event_signal_map *map = &base->sigmap; @@ -476,35 +452,32 @@ evmap_signal_del_(struct event_base *base, int sig, struct event *ev) GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal); - LIST_REMOVE(ev, ev_signal_next); - - if (LIST_FIRST(&ctx->events) == NULL) { + if (TAILQ_FIRST(&ctx->events) == TAILQ_LAST(&ctx->events, event_list)) { if (evsel->del(base, ev->ev_fd, 0, EV_SIGNAL, NULL) == -1) return (-1); } + TAILQ_REMOVE(&ctx->events, ev, ev_signal_next); + return (1); } void -evmap_signal_active_(struct event_base *base, evutil_socket_t sig, int ncalls) +evmap_signal_active(struct event_base *base, evutil_socket_t sig, int ncalls) { struct event_signal_map *map = &base->sigmap; struct evmap_signal *ctx; struct event *ev; - if (sig < 0 || sig >= map->nentries) - return; + EVUTIL_ASSERT(sig < map->nentries); GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal); - if (!ctx) - return; - LIST_FOREACH(ev, &ctx->events, ev_signal_next) - event_active_nolock_(ev, EV_SIGNAL, ncalls); + TAILQ_FOREACH(ev, &ctx->events, ev_signal_next) + event_active_nolock(ev, EV_SIGNAL, ncalls); } void * -evmap_io_get_fdinfo_(struct event_io_map *map, evutil_socket_t fd) +evmap_io_get_fdinfo(struct event_io_map *map, evutil_socket_t fd) { struct evmap_io *ctx; GET_IO_SLOT(ctx, map, fd, evmap_io); @@ -514,177 +487,6 @@ evmap_io_get_fdinfo_(struct event_io_map *map, evutil_socket_t fd) return NULL; } -/* Callback type for evmap_io_foreach_fd */ -typedef int (*evmap_io_foreach_fd_cb)( - struct event_base *, evutil_socket_t, struct evmap_io *, void *); - -/* Multipurpose helper function: Iterate over every file descriptor event_base - * for which we could have EV_READ or EV_WRITE events. For each such fd, call - * fn(base, signum, evmap_io, arg), where fn is the user-provided - * function, base is the event_base, signum is the signal number, evmap_io - * is an evmap_io structure containing a list of events pending on the - * file descriptor, and arg is the user-supplied argument. - * - * If fn returns 0, continue on to the next signal. Otherwise, return the same - * value that fn returned. - * - * Note that there is no guarantee that the file descriptors will be processed - * in any particular order. - */ -static int -evmap_io_foreach_fd(struct event_base *base, - evmap_io_foreach_fd_cb fn, - void *arg) -{ - evutil_socket_t fd; - struct event_io_map *iomap = &base->io; - int r = 0; -#ifdef EVMAP_USE_HT - struct event_map_entry **mapent; - HT_FOREACH(mapent, event_io_map, iomap) { - struct evmap_io *ctx = &(*mapent)->ent.evmap_io; - fd = (*mapent)->fd; -#else - for (fd = 0; fd < iomap->nentries; ++fd) { - struct evmap_io *ctx = iomap->entries[fd]; - if (!ctx) - continue; -#endif - if ((r = fn(base, fd, ctx, arg))) - break; - } - return r; -} - -/* Callback type for evmap_signal_foreach_signal */ -typedef int (*evmap_signal_foreach_signal_cb)( - struct event_base *, int, struct evmap_signal *, void *); - -/* Multipurpose helper function: Iterate over every signal number in the - * event_base for which we could have signal events. For each such signal, - * call fn(base, signum, evmap_signal, arg), where fn is the user-provided - * function, base is the event_base, signum is the signal number, evmap_signal - * is an evmap_signal structure containing a list of events pending on the - * signal, and arg is the user-supplied argument. - * - * If fn returns 0, continue on to the next signal. Otherwise, return the same - * value that fn returned. - */ -static int -evmap_signal_foreach_signal(struct event_base *base, - evmap_signal_foreach_signal_cb fn, - void *arg) -{ - struct event_signal_map *sigmap = &base->sigmap; - int r = 0; - int signum; - - for (signum = 0; signum < sigmap->nentries; ++signum) { - struct evmap_signal *ctx = sigmap->entries[signum]; - if (!ctx) - continue; - if ((r = fn(base, signum, ctx, arg))) - break; - } - return r; -} - -/* Helper for evmap_reinit_: tell the backend to add every fd for which we have - * pending events, with the appropriate combination of EV_READ, EV_WRITE, and - * EV_ET. */ -static int -evmap_io_reinit_iter_fn(struct event_base *base, evutil_socket_t fd, - struct evmap_io *ctx, void *arg) -{ - const struct eventop *evsel = base->evsel; - void *extra; - int *result = arg; - short events = 0; - struct event *ev; - EVUTIL_ASSERT(ctx); - - extra = ((char*)ctx) + sizeof(struct evmap_io); - if (ctx->nread) - events |= EV_READ; - if (ctx->nwrite) - events |= EV_WRITE; - if (ctx->nclose) - events |= EV_CLOSED; - if (evsel->fdinfo_len) - memset(extra, 0, evsel->fdinfo_len); - if (events && - (ev = LIST_FIRST(&ctx->events)) && - (ev->ev_events & EV_ET)) - events |= EV_ET; - if (evsel->add(base, fd, 0, events, extra) == -1) - *result = -1; - - return 0; -} - -/* Helper for evmap_reinit_: tell the backend to add every signal for which we - * have pending events. */ -static int -evmap_signal_reinit_iter_fn(struct event_base *base, - int signum, struct evmap_signal *ctx, void *arg) -{ - const struct eventop *evsel = base->evsigsel; - int *result = arg; - - if (!LIST_EMPTY(&ctx->events)) { - if (evsel->add(base, signum, 0, EV_SIGNAL, NULL) == -1) - *result = -1; - } - return 0; -} - -int -evmap_reinit_(struct event_base *base) -{ - int result = 0; - - evmap_io_foreach_fd(base, evmap_io_reinit_iter_fn, &result); - if (result < 0) - return -1; - evmap_signal_foreach_signal(base, evmap_signal_reinit_iter_fn, &result); - if (result < 0) - return -1; - return 0; -} - -/* Helper for evmap_delete_all_: delete every event in an event_dlist. */ -static int -delete_all_in_dlist(struct event_dlist *dlist) -{ - struct event *ev; - while ((ev = LIST_FIRST(dlist))) - event_del(ev); - return 0; -} - -/* Helper for evmap_delete_all_: delete every event pending on an fd. */ -static int -evmap_io_delete_all_iter_fn(struct event_base *base, evutil_socket_t fd, - struct evmap_io *io_info, void *arg) -{ - return delete_all_in_dlist(&io_info->events); -} - -/* Helper for evmap_delete_all_: delete every event pending on a signal. */ -static int -evmap_signal_delete_all_iter_fn(struct event_base *base, int signum, - struct evmap_signal *sig_info, void *arg) -{ - return delete_all_in_dlist(&sig_info->events); -} - -void -evmap_delete_all_(struct event_base *base) -{ - evmap_signal_foreach_signal(base, evmap_signal_delete_all_iter_fn, NULL); - evmap_io_foreach_fd(base, evmap_io_delete_all_iter_fn, NULL); -} - /** Per-fd structure for use with changelists. It keeps track, for each fd or * signal using the changelist, of where its entry in the changelist is. */ @@ -694,7 +496,7 @@ struct event_changelist_fdinfo { }; void -event_changelist_init_(struct event_changelist *changelist) +event_changelist_init(struct event_changelist *changelist) { changelist->changes = NULL; changelist->changes_size = 0; @@ -719,26 +521,10 @@ event_change_get_fdinfo(struct event_base *base, return (void*)ptr; } -/** Callback helper for event_changelist_assert_ok */ -static int -event_changelist_assert_ok_foreach_iter_fn( - struct event_base *base, - evutil_socket_t fd, struct evmap_io *io, void *arg) -{ - struct event_changelist *changelist = &base->changelist; - struct event_changelist_fdinfo *f; - f = (void*) - ( ((char*)io) + sizeof(struct evmap_io) ); - if (f->idxplus1) { - struct event_change *c = &changelist->changes[f->idxplus1 - 1]; - EVUTIL_ASSERT(c->fd == fd); - } - return 0; -} - +#ifdef DEBUG_CHANGELIST /** Make sure that the changelist is consistent with the evmap structures. */ static void -event_changelist_assert_ok(struct event_base *base) +event_changelist_check(struct event_base *base) { int i; struct event_changelist *changelist = &base->changelist; @@ -753,19 +539,25 @@ event_changelist_assert_ok(struct event_base *base) EVUTIL_ASSERT(f->idxplus1 == i + 1); } - evmap_io_foreach_fd(base, - event_changelist_assert_ok_foreach_iter_fn, - NULL); + for (i = 0; i < base->io.nentries; ++i) { + struct evmap_io *io = base->io.entries[i]; + struct event_changelist_fdinfo *f; + if (!io) + continue; + f = (void*) + ( ((char*)io) + sizeof(struct evmap_io) ); + if (f->idxplus1) { + struct event_change *c = &changelist->changes[f->idxplus1 - 1]; + EVUTIL_ASSERT(c->fd == i); + } + } } - -#ifdef DEBUG_CHANGELIST -#define event_changelist_check(base) event_changelist_assert_ok((base)) #else #define event_changelist_check(base) ((void)0) #endif void -event_changelist_remove_all_(struct event_changelist *changelist, +event_changelist_remove_all(struct event_changelist *changelist, struct event_base *base) { int i; @@ -786,11 +578,11 @@ event_changelist_remove_all_(struct event_changelist *changelist, } void -event_changelist_freemem_(struct event_changelist *changelist) +event_changelist_freemem(struct event_changelist *changelist) { if (changelist->changes) mm_free(changelist->changes); - event_changelist_init_(changelist); /* zero it all out. */ + event_changelist_init(changelist); /* zero it all out. */ } /** Increase the size of 'changelist' to hold more changes. */ @@ -852,7 +644,7 @@ event_changelist_get_or_construct(struct event_changelist *changelist, } int -event_changelist_add_(struct event_base *base, evutil_socket_t fd, short old, short events, +event_changelist_add(struct event_base *base, evutil_socket_t fd, short old, short events, void *p) { struct event_changelist *changelist = &base->changelist; @@ -877,17 +669,13 @@ event_changelist_add_(struct event_base *base, evutil_socket_t fd, short old, sh change->write_change = EV_CHANGE_ADD | (events & (EV_ET|EV_PERSIST|EV_SIGNAL)); } - if (events & EV_CLOSED) { - change->close_change = EV_CHANGE_ADD | - (events & (EV_ET|EV_PERSIST|EV_SIGNAL)); - } event_changelist_check(base); return (0); } int -event_changelist_del_(struct event_base *base, evutil_socket_t fd, short old, short events, +event_changelist_del(struct event_base *base, evutil_socket_t fd, short old, short events, void *p) { struct event_changelist *changelist = &base->changelist; @@ -900,11 +688,14 @@ event_changelist_del_(struct event_base *base, evutil_socket_t fd, short old, sh if (!change) return -1; - /* A delete on an event set that doesn't contain the event to be - deleted produces a no-op. This effectively emoves any previous - uncommitted add, rather than replacing it: on those platforms where - "add, delete, dispatch" is not the same as "no-op, dispatch", we - want the no-op behavior. + /* A delete removes any previous add, rather than replacing it: + on those platforms where "add, delete, dispatch" is not the same + as "no-op, dispatch", we want the no-op behavior. + + As well as checking the current operation we should also check + the original set of events to make sure were not ignoring + the case where the add operation is present on an event that + was already set. If we have a no-op item, we could remove it it from the list entirely, but really there's not much point: skipping the no-op @@ -916,140 +707,93 @@ event_changelist_del_(struct event_base *base, evutil_socket_t fd, short old, sh */ if (events & (EV_READ|EV_SIGNAL)) { - if (!(change->old_events & (EV_READ | EV_SIGNAL))) + if (!(change->old_events & (EV_READ | EV_SIGNAL)) && + (change->read_change & EV_CHANGE_ADD)) change->read_change = 0; else change->read_change = EV_CHANGE_DEL; } if (events & EV_WRITE) { - if (!(change->old_events & EV_WRITE)) + if (!(change->old_events & EV_WRITE) && + (change->write_change & EV_CHANGE_ADD)) change->write_change = 0; else change->write_change = EV_CHANGE_DEL; } - if (events & EV_CLOSED) { - if (!(change->old_events & EV_CLOSED)) - change->close_change = 0; - else - change->close_change = EV_CHANGE_DEL; - } event_changelist_check(base); return (0); } -/* Helper for evmap_check_integrity_: verify that all of the events pending on - * given fd are set up correctly, and that the nread and nwrite counts on that - * fd are correct. */ -static int -evmap_io_check_integrity_fn(struct event_base *base, evutil_socket_t fd, - struct evmap_io *io_info, void *arg) +void +evmap_check_integrity(struct event_base *base) { - struct event *ev; - int n_read = 0, n_write = 0, n_close = 0; +#define EVLIST_X_SIGFOUND 0x1000 +#define EVLIST_X_IOFOUND 0x2000 - /* First, make sure the list itself isn't corrupt. Otherwise, - * running LIST_FOREACH could be an exciting adventure. */ - EVUTIL_ASSERT_LIST_OK(&io_info->events, event, ev_io_next); + evutil_socket_t i; + struct event *ev; + struct event_io_map *io = &base->io; + struct event_signal_map *sigmap = &base->sigmap; +#ifdef EVMAP_USE_HT + struct event_map_entry **mapent; +#endif + int nsignals, ntimers, nio; + nsignals = ntimers = nio = 0; - LIST_FOREACH(ev, &io_info->events, ev_io_next) { + TAILQ_FOREACH(ev, &base->eventqueue, ev_next) { EVUTIL_ASSERT(ev->ev_flags & EVLIST_INSERTED); - EVUTIL_ASSERT(ev->ev_fd == fd); - EVUTIL_ASSERT(!(ev->ev_events & EV_SIGNAL)); - EVUTIL_ASSERT((ev->ev_events & (EV_READ|EV_WRITE|EV_CLOSED))); - if (ev->ev_events & EV_READ) - ++n_read; - if (ev->ev_events & EV_WRITE) - ++n_write; - if (ev->ev_events & EV_CLOSED) - ++n_close; + EVUTIL_ASSERT(ev->ev_flags & EVLIST_INIT); + ev->ev_flags &= ~(EVLIST_X_SIGFOUND|EVLIST_X_IOFOUND); } - EVUTIL_ASSERT(n_read == io_info->nread); - EVUTIL_ASSERT(n_write == io_info->nwrite); - EVUTIL_ASSERT(n_close == io_info->nclose); - - return 0; -} +#ifdef EVMAP_USE_HT + HT_FOREACH(mapent, event_io_map, io) { + struct evmap_io *ctx = &(*mapent)->ent.evmap_io; + i = (*mapent)->fd; +#else + for (i = 0; i < io->nentries; ++i) { + struct evmap_io *ctx = io->entries[i]; -/* Helper for evmap_check_integrity_: verify that all of the events pending - * on given signal are set up correctly. */ -static int -evmap_signal_check_integrity_fn(struct event_base *base, - int signum, struct evmap_signal *sig_info, void *arg) -{ - struct event *ev; - /* First, make sure the list itself isn't corrupt. */ - EVUTIL_ASSERT_LIST_OK(&sig_info->events, event, ev_signal_next); + if (!ctx) + continue; +#endif - LIST_FOREACH(ev, &sig_info->events, ev_io_next) { - EVUTIL_ASSERT(ev->ev_flags & EVLIST_INSERTED); - EVUTIL_ASSERT(ev->ev_fd == signum); - EVUTIL_ASSERT((ev->ev_events & EV_SIGNAL)); - EVUTIL_ASSERT(!(ev->ev_events & (EV_READ|EV_WRITE|EV_CLOSED))); + TAILQ_FOREACH(ev, &ctx->events, ev_io_next) { + EVUTIL_ASSERT(!(ev->ev_flags & EVLIST_X_IOFOUND)); + EVUTIL_ASSERT(ev->ev_fd == i); + ev->ev_flags |= EVLIST_X_IOFOUND; + nio++; + } } - return 0; -} -void -evmap_check_integrity_(struct event_base *base) -{ - evmap_io_foreach_fd(base, evmap_io_check_integrity_fn, NULL); - evmap_signal_foreach_signal(base, evmap_signal_check_integrity_fn, NULL); - - if (base->evsel->add == event_changelist_add_) - event_changelist_assert_ok(base); -} - -/* Helper type for evmap_foreach_event_: Bundles a function to call on every - * event, and the user-provided void* to use as its third argument. */ -struct evmap_foreach_event_helper { - event_base_foreach_event_cb fn; - void *arg; -}; + for (i = 0; i < sigmap->nentries; ++i) { + struct evmap_signal *ctx = sigmap->entries[i]; + if (!ctx) + continue; -/* Helper for evmap_foreach_event_: calls a provided function on every event - * pending on a given fd. */ -static int -evmap_io_foreach_event_fn(struct event_base *base, evutil_socket_t fd, - struct evmap_io *io_info, void *arg) -{ - struct evmap_foreach_event_helper *h = arg; - struct event *ev; - int r; - LIST_FOREACH(ev, &io_info->events, ev_io_next) { - if ((r = h->fn(base, ev, h->arg))) - return r; + TAILQ_FOREACH(ev, &ctx->events, ev_signal_next) { + EVUTIL_ASSERT(!(ev->ev_flags & EVLIST_X_SIGFOUND)); + EVUTIL_ASSERT(ev->ev_fd == i); + ev->ev_flags |= EVLIST_X_SIGFOUND; + nsignals++; + } } - return 0; -} -/* Helper for evmap_foreach_event_: calls a provided function on every event - * pending on a given signal. */ -static int -evmap_signal_foreach_event_fn(struct event_base *base, int signum, - struct evmap_signal *sig_info, void *arg) -{ - struct event *ev; - struct evmap_foreach_event_helper *h = arg; - int r; - LIST_FOREACH(ev, &sig_info->events, ev_signal_next) { - if ((r = h->fn(base, ev, h->arg))) - return r; + TAILQ_FOREACH(ev, &base->eventqueue, ev_next) { + if (ev->ev_events & (EV_READ|EV_WRITE)) { + EVUTIL_ASSERT(ev->ev_flags & EVLIST_X_IOFOUND); + --nio; + } + if (ev->ev_events & EV_SIGNAL) { + EVUTIL_ASSERT(ev->ev_flags & EVLIST_X_SIGFOUND); + --nsignals; + } } - return 0; -} -int -evmap_foreach_event_(struct event_base *base, - event_base_foreach_event_cb fn, void *arg) -{ - struct evmap_foreach_event_helper h; - int r; - h.fn = fn; - h.arg = arg; - if ((r = evmap_io_foreach_fd(base, evmap_io_foreach_event_fn, &h))) - return r; - return evmap_signal_foreach_signal(base, evmap_signal_foreach_event_fn, &h); + EVUTIL_ASSERT(nio == 0); + EVUTIL_ASSERT(nsignals == 0); + /* There is no "EVUTIL_ASSERT(ntimers == 0)": eventqueue is only for + * pending signals and io events. + */ } - |