diff options
author | kikht <kikht@yandex-team.ru> | 2022-02-10 16:45:14 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:14 +0300 |
commit | 194cae0e8855b11be2005e1eff12c660c3ee9774 (patch) | |
tree | ed29c437b616690880c017855ebe0be34fdf81a2 /contrib/libs/libevent/evmap.c | |
parent | 49116032d905455a7b1c994e4a696afc885c1e71 (diff) | |
download | ydb-194cae0e8855b11be2005e1eff12c660c3ee9774.tar.gz |
Restoring authorship annotation for <kikht@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/libevent/evmap.c')
-rw-r--r-- | contrib/libs/libevent/evmap.c | 852 |
1 files changed, 426 insertions, 426 deletions
diff --git a/contrib/libs/libevent/evmap.c b/contrib/libs/libevent/evmap.c index e4e35c6877..11c7617f79 100644 --- a/contrib/libs/libevent/evmap.c +++ b/contrib/libs/libevent/evmap.c @@ -24,26 +24,26 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "event2/event-config.h" -#include "evconfig-private.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> -#include <limits.h> +#include <limits.h> #include <signal.h> #include <string.h> #include <time.h> @@ -57,16 +57,16 @@ write on a given fd, and the number of each. */ struct evmap_io { - struct event_dlist events; + struct event_dlist events; ev_uint16_t nread; ev_uint16_t nwrite; - ev_uint16_t nclose; + 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_dlist events; }; /* On some platforms, fds start at 0 and increment by 1 as they are @@ -113,38 +113,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) { @@ -186,14 +186,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 @@ -208,15 +208,15 @@ evmap_make_space(struct event_signal_map *map, int slot, int msize) int nentries = map->nentries ? map->nentries : 32; void **tmp; - if (slot > INT_MAX / 2) - return (-1); - + if (slot > INT_MAX / 2) + return (-1); + while (nentries <= slot) nentries <<= 1; - if (nentries > INT_MAX / msize) - return (-1); - + if (nentries > INT_MAX / msize) + return (-1); + tmp = (void **)mm_realloc(map->entries, nentries * msize); if (tmp == NULL) return (-1); @@ -232,14 +232,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; @@ -260,22 +260,22 @@ evmap_signal_clear_(struct event_signal_map *ctx) static void evmap_io_init(struct evmap_io *entry) { - LIST_INIT(&entry->events); + LIST_INIT(&entry->events); entry->nread = 0; entry->nwrite = 0; - entry->nclose = 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, nclose, retval = 0; short res = 0, old = 0; struct event *old_ev; @@ -295,14 +295,14 @@ evmap_io_add_(struct event_base *base, evutil_socket_t fd, struct event *ev) nread = ctx->nread; nwrite = ctx->nwrite; - nclose = ctx->nclose; + nclose = ctx->nclose; if (nread) old |= EV_READ; if (nwrite) old |= EV_WRITE; - if (nclose) - old |= EV_CLOSED; + if (nclose) + old |= EV_CLOSED; if (ev->ev_events & EV_READ) { if (++nread == 1) @@ -312,17 +312,17 @@ 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 (ev->ev_events & EV_CLOSED) { + if (++nclose == 1) + res |= EV_CLOSED; + } + if (EVUTIL_UNLIKELY(nread > 0xffff || nwrite > 0xffff || nclose > 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 = LIST_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); @@ -342,8 +342,8 @@ 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); + ctx->nclose = (ev_uint16_t) nclose; + LIST_INSERT_HEAD(&ctx->events, ev, ev_io_next); return (retval); } @@ -351,12 +351,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, nclose, retval = 0; short res = 0, old = 0; if (fd < 0) @@ -373,14 +373,14 @@ evmap_io_del_(struct event_base *base, evutil_socket_t fd, struct event *ev) nread = ctx->nread; nwrite = ctx->nwrite; - nclose = ctx->nclose; + nclose = ctx->nclose; if (nread) old |= EV_READ; if (nwrite) old |= EV_WRITE; - if (nclose) - old |= EV_CLOSED; + if (nclose) + old |= EV_CLOSED; if (ev->ev_events & EV_READ) { if (--nread == 0) @@ -392,48 +392,48 @@ 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 (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, (ev->ev_events & EV_ET) | res, extra) == -1) { - retval = -1; - } else { - retval = 1; - } + if (evsel->del(base, ev->ev_fd, + old, (ev->ev_events & EV_ET) | res, extra) == -1) { + retval = -1; + } else { + retval = 1; + } } ctx->nread = nread; ctx->nwrite = nwrite; - ctx->nclose = nclose; - LIST_REMOVE(ev, ev_io_next); + ctx->nclose = nclose; + LIST_REMOVE(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; + if (fd < 0 || fd >= io->nentries) + return; #endif GET_IO_SLOT(ctx, io, fd, evmap_io); - if (NULL == ctx) - return; - LIST_FOREACH(ev, &ctx->events, ev_io_next) { + if (NULL == ctx) + return; + LIST_FOREACH(ev, &ctx->events, ev_io_next) { if (ev->ev_events & (events & ~EV_ET)) - event_active_nolock_(ev, ev->ev_events & events, 1); + event_active_nolock_(ev, ev->ev_events & events, 1); } } @@ -442,20 +442,20 @@ 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); + LIST_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; struct evmap_signal *ctx = NULL; - if (sig < 0 || sig >= NSIG) - return (-1); - + if (sig < 0 || sig >= NSIG) + return (-1); + if (sig >= map->nentries) { if (evmap_make_space( map, sig, sizeof(struct evmap_signal *)) == -1) @@ -464,32 +464,32 @@ 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 (LIST_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); + LIST_INSERT_HEAD(&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; struct evmap_signal *ctx; - if (sig < 0 || sig >= map->nentries) + if (sig < 0 || sig >= map->nentries) return (-1); GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal); - LIST_REMOVE(ev, ev_signal_next); - - if (LIST_FIRST(&ctx->events) == NULL) { + LIST_REMOVE(ev, ev_signal_next); + + if (LIST_FIRST(&ctx->events) == NULL) { if (evsel->del(base, ev->ev_fd, 0, EV_SIGNAL, NULL) == -1) return (-1); } @@ -498,24 +498,24 @@ evmap_signal_del_(struct event_base *base, int sig, struct event *ev) } 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; + if (sig < 0 || sig >= map->nentries) + return; 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); + if (!ctx) + return; + LIST_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); @@ -525,177 +525,177 @@ 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); -} - +/* 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. */ @@ -705,7 +705,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; @@ -730,26 +730,26 @@ 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; -} - +/** 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; +} + /** Make sure that the changelist is consistent with the evmap structures. */ static void -event_changelist_assert_ok(struct event_base *base) +event_changelist_assert_ok(struct event_base *base) { int i; struct event_changelist *changelist = &base->changelist; @@ -764,19 +764,19 @@ 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); + evmap_io_foreach_fd(base, + event_changelist_assert_ok_foreach_iter_fn, + NULL); } - -#ifdef DEBUG_CHANGELIST -#define event_changelist_check(base) event_changelist_assert_ok((base)) + +#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; @@ -797,11 +797,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. */ @@ -863,13 +863,13 @@ 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; struct event_changelist_fdinfo *fdinfo = p; struct event_change *change; - ev_uint8_t evchange = EV_CHANGE_ADD | (events & (EV_ET|EV_PERSIST|EV_SIGNAL)); + ev_uint8_t evchange = EV_CHANGE_ADD | (events & (EV_ET|EV_PERSIST|EV_SIGNAL)); event_changelist_check(base); @@ -881,25 +881,25 @@ event_changelist_add_(struct event_base *base, evutil_socket_t fd, short old, sh * since the delete might fail (because the fd had been closed since * the last add, for instance. */ - if (events & (EV_READ|EV_SIGNAL)) - change->read_change = evchange; - if (events & EV_WRITE) - change->write_change = evchange; - if (events & EV_CLOSED) - change->close_change = evchange; + if (events & (EV_READ|EV_SIGNAL)) + change->read_change = evchange; + if (events & EV_WRITE) + change->write_change = evchange; + if (events & EV_CLOSED) + change->close_change = evchange; 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; struct event_changelist_fdinfo *fdinfo = p; struct event_change *change; - ev_uint8_t del = EV_CHANGE_DEL | (events & EV_ET); + ev_uint8_t del = EV_CHANGE_DEL | (events & EV_ET); event_changelist_check(base); change = event_changelist_get_or_construct(changelist, fd, old, fdinfo); @@ -907,11 +907,11 @@ 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 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. 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 @@ -923,140 +923,140 @@ 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 = 0; else - change->read_change = del; + change->read_change = del; } if (events & EV_WRITE) { - if (!(change->old_events & EV_WRITE)) + if (!(change->old_events & EV_WRITE)) change->write_change = 0; else - change->write_change = del; - } - if (events & EV_CLOSED) { - if (!(change->old_events & EV_CLOSED)) - change->close_change = 0; - else - change->close_change = del; + change->write_change = del; } + if (events & EV_CLOSED) { + if (!(change->old_events & EV_CLOSED)) + change->close_change = 0; + else + change->close_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) +/* 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) { struct event *ev; - int n_read = 0, n_write = 0, n_close = 0; - - /* 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); + int n_read = 0, n_write = 0, n_close = 0; - LIST_FOREACH(ev, &io_info->events, ev_io_next) { + /* 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); + + LIST_FOREACH(ev, &io_info->events, ev_io_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_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(n_read == io_info->nread); - EVUTIL_ASSERT(n_write == io_info->nwrite); - EVUTIL_ASSERT(n_close == io_info->nclose); - - return 0; -} - -/* 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); - - 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))); + EVUTIL_ASSERT(n_read == io_info->nread); + EVUTIL_ASSERT(n_write == io_info->nwrite); + EVUTIL_ASSERT(n_close == io_info->nclose); + + return 0; +} + +/* 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); + + 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))); } - 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; -}; - -/* 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; + 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; +}; + +/* 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; } - 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; + 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; } - 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); + 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); } - + |