Skip to content

Commit

Permalink
Remove the eventqueue list and the ev_next pointers.
Browse files Browse the repository at this point in the history
Those pointers were once used to maintain a complete list of
inserted IO and signal events.  But such a list is now available by
walking over ev_io_map and ev_signal_map!  So all they did was
require extra pointer operations to maintain, and extra 8-16 bytes
of storage in each struct event.

To be cowardly and keep the option of going back to having this
redundancy, I'm wrapping the removed code in a set of ifdefs.

This is a first cut; it needs cleanups and stress-testing!!  In
particular, it just plain disables a couple of functions that could
probably be saved.

There seems to be a need for an evmap_{io,signal}_foreach() or something.
  • Loading branch information
nmathewson committed Jan 27, 2012
1 parent 7622d26 commit 604569b
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 8 deletions.
2 changes: 2 additions & 0 deletions event-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,10 @@ struct event_base {
/** Mapping from signal numbers to enabled (added) events. */
struct event_signal_map sigmap;

#ifdef _EVENT_USE_EVENTLIST
/** All events that have been enabled (added) in this event_base */
struct event_list eventqueue;
#endif

/** Stored timeval; used to detect when time is running backwards. */
struct timeval event_tv;
Expand Down
21 changes: 13 additions & 8 deletions event.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,9 @@ event_base_new_with_config(const struct event_config *cfg)
gettime(base, &base->event_tv);

min_heap_ctor(&base->timeheap);
#ifdef _EVENT_USE_EVENTLIST
TAILQ_INIT(&base->eventqueue);
#endif
base->sig.ev_signal_pair[0] = -1;
base->sig.ev_signal_pair[1] = -1;
base->th_notify_fd[0] = -1;
Expand Down Expand Up @@ -764,14 +766,8 @@ event_base_free(struct event_base *base)
}

/* Delete all non-internal events. */
for (ev = TAILQ_FIRST(&base->eventqueue); ev; ) {
struct event *next = TAILQ_NEXT(ev, ev_next);
if (!(ev->ev_flags & EVLIST_INTERNAL)) {
event_del(ev);
++n_deleted;
}
ev = next;
}
evmap_signal_delete_all(base);
evmap_io_delete_all(base);
while ((ev = min_heap_top(&base->timeheap)) != NULL) {
event_del(ev);
++n_deleted;
Expand Down Expand Up @@ -821,7 +817,9 @@ event_base_free(struct event_base *base)

mm_free(base->activequeues);

#ifdef _EVENT_USE_EVENTLIST
EVUTIL_ASSERT(TAILQ_EMPTY(&base->eventqueue));
#endif

evmap_io_clear(&base->io);
evmap_signal_clear(&base->sigmap);
Expand Down Expand Up @@ -2638,7 +2636,9 @@ event_queue_remove_inserted(struct event_base *base, struct event *ev)
}
DECR_EVENT_COUNT(base, ev);
ev->ev_flags &= ~EVLIST_INSERTED;
#ifdef _EVENT_USE_EVENTLIST
TAILQ_REMOVE(&base->eventqueue, ev, ev_next);
#endif
}
static void
event_queue_remove_active(struct event_base *base, struct event *ev)
Expand Down Expand Up @@ -2743,7 +2743,9 @@ event_queue_insert_inserted(struct event_base *base, struct event *ev)

ev->ev_flags |= EVLIST_INSERTED;

#ifdef _EVENT_USE_EVENTLIST
TAILQ_INSERT_TAIL(&base->eventqueue, ev, ev_next);
#endif
}

static void
Expand Down Expand Up @@ -3030,6 +3032,8 @@ evthread_make_base_notifiable(struct event_base *base)
void
event_base_dump_events(struct event_base *base, FILE *output)
{
#ifdef _EVENT_USE_EVENTLIST
/* re-enable XXXXXX */
struct event *e;
int i;
fprintf(output, "Inserted events:\n");
Expand All @@ -3056,6 +3060,7 @@ event_base_dump_events(struct event_base *base, FILE *output)
(e->ev_res&EV_TIMEOUT)?" Timeout active":"");
}
}
#endif
}

void
Expand Down
3 changes: 3 additions & 0 deletions evmap-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ void *evmap_io_get_fdinfo(struct event_io_map *ctx, evutil_socket_t fd);
int evmap_io_reinit(struct event_base *base);
int evmap_signal_reinit(struct event_base *base);

int evmap_io_delete_all(struct event_base *base);
int evmap_signal_delete_all(struct event_base *base);

void evmap_check_integrity(struct event_base *base);

#endif /* _EVMAP_H_ */
42 changes: 42 additions & 0 deletions evmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,45 @@ evmap_signal_reinit(struct event_base *base)
return res;
}

int
evmap_io_delete_all(struct event_base *base)
{
struct event_io_map *io = &base->io;

#ifdef EVMAP_USE_HT
struct event_map_entry **mapent;
HT_FOREACH(mapent, event_io_map, io) {
struct evmap_io *ctx = &(*mapent)->ent.evmap_io;
#else
evutil_socket_t i;
for (i = 0; i < io->nentries; ++i) {
struct evmap_io *ctx = io->entries[i];
if (!ctx)
continue;
#endif
while (LIST_FIRST(&ctx->events))
event_del(LIST_FIRST(&ctx->events));
}

return 0;
}

int
evmap_signal_delete_all(struct event_base *base)
{
struct event_signal_map *sigmap = &base->sigmap;
int i;

for (i = 0; i < sigmap->nentries; ++i) {
struct evmap_signal *ctx = sigmap->entries[i];
if (!ctx)
continue;
while (!LIST_EMPTY(&ctx->events))
event_del(LIST_FIRST(&ctx->events));
}
return 0;
}

/** 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.
*/
Expand Down Expand Up @@ -798,6 +837,8 @@ evmap_check_integrity(struct event_base *base)
int nsignals, ntimers, nio;
nsignals = ntimers = nio = 0;

#ifdef _EVENT_USE_EVENTLIST
/* XXXXX no-eventlist implementations can use some of this, surely? */
TAILQ_FOREACH(ev, &base->eventqueue, ev_next) {
EVUTIL_ASSERT(ev->ev_flags & EVLIST_INSERTED);
EVUTIL_ASSERT(ev->ev_flags & EVLIST_INIT);
Expand Down Expand Up @@ -848,6 +889,7 @@ evmap_check_integrity(struct event_base *base)
}
}

#endif
EVUTIL_ASSERT(nio == 0);
EVUTIL_ASSERT(nsignals == 0);
/* There is no "EVUTIL_ASSERT(ntimers == 0)": eventqueue is only for
Expand Down
2 changes: 2 additions & 0 deletions include/event2/event_struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ struct { \
struct event_base;
struct event {
TAILQ_ENTRY(event) ev_active_next;
#ifdef _EVENT_USE_EVENTLIST
TAILQ_ENTRY(event) ev_next;
#endif
/* for managing timeouts */
union {
TAILQ_ENTRY(event) ev_next_with_common_timeout;
Expand Down

0 comments on commit 604569b

Please sign in to comment.