From 0617a818204397790e5e4c9bcb9e91ae5ea7817a Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sun, 14 Nov 2010 19:25:54 -0500 Subject: [PATCH 1/3] Make EVLOOP_ONCE ignore internal events Merely getting an internal notification event from having an event added or deleted from another thread should not cause event_base_loop(base, EVLOOP_ONCE) to exit; previously, it did. --- event.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/event.c b/event.c index 37217729..bde4d1cc 100644 --- a/event.c +++ b/event.c @@ -134,7 +134,7 @@ static void event_queue_insert(struct event_base *, struct event *, int); static void event_queue_remove(struct event_base *, struct event *, int); static int event_haveevents(struct event_base *); -static void event_process_active(struct event_base *); +static int event_process_active(struct event_base *); static int timeout_next(struct event_base *, struct timeval **); static void timeout_process(struct event_base *); @@ -1341,19 +1341,19 @@ event_process_deferred_callbacks(struct deferred_cb_queue *queue, int *breakptr) * priority ones. */ -static void +static int event_process_active(struct event_base *base) { /* Caller must hold th_base_lock */ struct event_list *activeq = NULL; - int i, c; + int i, c = 0; for (i = 0; i < base->nactivequeues; ++i) { if (TAILQ_FIRST(&base->activequeues[i]) != NULL) { activeq = &base->activequeues[i]; c = event_process_active_single_queue(base, activeq); if (c < 0) - return; + return -1; else if (c > 0) break; /* Processed a real event; do not * consider lower-priority events */ @@ -1363,6 +1363,7 @@ event_process_active(struct event_base *base) } event_process_deferred_callbacks(&base->defer_queue,&base->event_break); + return c; } /* @@ -1547,8 +1548,10 @@ event_base_loop(struct event_base *base, int flags) timeout_process(base); if (N_ACTIVE_CALLBACKS(base)) { - event_process_active(base); - if (!base->event_count_active && (flags & EVLOOP_ONCE)) + int n = event_process_active(base); + if ((flags & EVLOOP_ONCE) + && base->event_count_active == 0 + && n != 0) done = 1; } else if (flags & EVLOOP_NONBLOCK) done = 1; From 2d5e1bd0be546efb848006652b8df612d6d3d681 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sun, 14 Nov 2010 19:32:13 -0500 Subject: [PATCH 2/3] Do not let EVLOOP_ONCE exit the loop until all deferred callbacks have run --- event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event.c b/event.c index bde4d1cc..4e429273 100644 --- a/event.c +++ b/event.c @@ -1550,7 +1550,7 @@ event_base_loop(struct event_base *base, int flags) if (N_ACTIVE_CALLBACKS(base)) { int n = event_process_active(base); if ((flags & EVLOOP_ONCE) - && base->event_count_active == 0 + && N_ACTIVE_CALLBACKS(base) == 0 && n != 0) done = 1; } else if (flags & EVLOOP_NONBLOCK) From 057a51468e1368384478788800f66c6d82e2bce3 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sun, 14 Nov 2010 19:34:49 -0500 Subject: [PATCH 3/3] Clarify EVLOOP_* documentation to be more precise. --- include/event2/event.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/event2/event.h b/include/event2/event.h index fa0f625d..1cba7708 100644 --- a/include/event2/event.h +++ b/include/event2/event.h @@ -301,8 +301,12 @@ int event_base_set(struct event_base *, struct event *); event_loop() flags */ /*@{*/ -#define EVLOOP_ONCE 0x01 /**< Block at most once. */ -#define EVLOOP_NONBLOCK 0x02 /**< Do not block. */ +/** Block until we have an active event, then exit once all active events + * have had their callbacks run. */ +#define EVLOOP_ONCE 0x01 +/** Do not block: see which events are ready now, run the callbacks + * highest-priority ones, then exit. */ +#define EVLOOP_NONBLOCK 0x02 /*@}*/ /**