]> granicus.if.org Git - libevent/commitdiff
Make EVLOOP_ONCE ignore internal events
authorNick Mathewson <nickm@torproject.org>
Mon, 15 Nov 2010 00:25:54 +0000 (19:25 -0500)
committerNick Mathewson <nickm@torproject.org>
Mon, 15 Nov 2010 00:25:54 +0000 (19:25 -0500)
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

diff --git a/event.c b/event.c
index 37217729c2ca6336b54996fd716765a01c228d58..bde4d1cc8df0aec6555d1fea7ea52dfa5a495fc5 100644 (file)
--- 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;