X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=libevent%2Fevmap.c;h=69c1067d89fbcc99f653cfc8c5c2e50a109aab5e;hp=5521626cf2431137f542c94d406801fef2833328;hb=ffead2c5a73949fea4e8462f99a6c2555568473b;hpb=cdb7047fb6897c1ad8b4ac264001d44154bf144d diff --git a/libevent/evmap.c b/libevent/evmap.c index 5521626c..69c1067d 100644 --- a/libevent/evmap.c +++ b/libevent/evmap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2010 Niels Provos and Nick Mathewson + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -127,7 +127,8 @@ HT_GENERATE(event_io_map, event_map_entry, map_node, hashsocket, eqsocket, }, \ { \ _ent = mm_calloc(1,sizeof(struct event_map_entry)+fdinfo_len); \ - EVUTIL_ASSERT(_ent); \ + if (EVUTIL_UNLIKELY(_ent == NULL)) \ + return (-1); \ _ent->fd = slot; \ (ctor)(&_ent->ent.type); \ _HT_FOI_INSERT(map_node, map, &_key, _ent, ptr) \ @@ -148,6 +149,7 @@ void evmap_io_clear(struct event_io_map *ctx) next = HT_NEXT_RMV(event_io_map, ctx, ent); mm_free(this); } + HT_CLEAR(event_io_map, ctx); /* remove all storage held by the ctx. */ } #endif @@ -158,15 +160,16 @@ void evmap_io_clear(struct event_io_map *ctx) (x) = (struct type *)((map)->entries[slot]) /* As GET_SLOT, but construct the entry for 'slot' if it is not present, by allocating enough memory for a 'struct type', and initializing the new - value by calling the function 'ctor' on it. + value by calling the function 'ctor' on it. Makes the function + return -1 on allocation failure. */ #define GET_SIGNAL_SLOT_AND_CTOR(x, map, slot, type, ctor, fdinfo_len) \ do { \ if ((map)->entries[slot] == NULL) { \ - EVUTIL_ASSERT(ctor != NULL); \ (map)->entries[slot] = \ mm_calloc(1,sizeof(struct type)+fdinfo_len); \ - EVUTIL_ASSERT((map)->entries[slot] != NULL); \ + if (EVUTIL_UNLIKELY((map)->entries[slot] == NULL)) \ + return (-1); \ (ctor)((struct type *)(map)->entries[slot]); \ } \ (x) = (struct type *)((map)->entries[slot]); \ @@ -722,3 +725,75 @@ event_changelist_del(struct event_base *base, evutil_socket_t fd, short old, sho return (0); } +void +evmap_check_integrity(struct event_base *base) +{ +#define EVLIST_X_SIGFOUND 0x1000 +#define EVLIST_X_IOFOUND 0x2000 + + 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; + + TAILQ_FOREACH(ev, &base->eventqueue, ev_next) { + EVUTIL_ASSERT(ev->ev_flags & EVLIST_INSERTED); + EVUTIL_ASSERT(ev->ev_flags & EVLIST_INIT); + ev->ev_flags &= ~(EVLIST_X_SIGFOUND|EVLIST_X_IOFOUND); + } + +#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]; + + if (!ctx) + continue; +#endif + + 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++; + } + } + + for (i = 0; i < sigmap->nentries; ++i) { + struct evmap_signal *ctx = sigmap->entries[i]; + if (!ctx) + continue; + + 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++; + } + } + + 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; + } + } + + EVUTIL_ASSERT(nio == 0); + EVUTIL_ASSERT(nsignals == 0); + /* There is no "EVUTIL_ASSERT(ntimers == 0)": eventqueue is only for + * pending signals and io events. + */ +}