]> granicus.if.org Git - libevent/commitdiff
deal correctly with deleting an event, now that we allow multiple callbacks
authorNiels Provos <provos@gmail.com>
Wed, 10 Apr 2002 03:15:19 +0000 (03:15 +0000)
committerNiels Provos <provos@gmail.com>
Wed, 10 Apr 2002 03:15:19 +0000 (03:15 +0000)
for signal delivery.

svn:r20

event.c
event.h
select.c

diff --git a/event.c b/event.c
index 882830d86ac977f1c042862f70f57d2d69b771a9..aa5f295ddd84435565258e40c8af9e85d134a829 100644 (file)
--- a/event.c
+++ b/event.c
@@ -138,13 +138,20 @@ void
 event_process_active(void)
 {
        struct event *ev;
+       short ncalls;
 
        for (ev = TAILQ_FIRST(&activequeue); ev;
            ev = TAILQ_FIRST(&activequeue)) {
                event_queue_remove(ev, EVLIST_ACTIVE);
                
-               while (ev->ev_ncalls--)
+               /* Allows deletes to work */
+               ncalls = ev->ev_ncalls;
+               ev->ev_pncalls = &ncalls;
+               while (ncalls) {
+                       ncalls--;
+                       ev->ev_ncalls = ncalls;
                        (*ev->ev_callback)(ev->ev_fd, ev->ev_res, ev->ev_arg);
+               }
        }
 }
 
@@ -307,6 +314,12 @@ event_del(struct event *ev)
 
        assert(!(ev->ev_flags & ~EVLIST_ALL));
 
+       /* See if we are just active executing this event in a loop */
+       if (ev->ev_ncalls && ev->ev_pncalls) {
+               /* Abort loop */
+               *ev->ev_pncalls = 0;
+       }
+
        if (ev->ev_flags & EVLIST_TIMEOUT)
                event_queue_remove(ev, EVLIST_TIMEOUT);
 
@@ -329,6 +342,7 @@ event_active(struct event *ev, int res, short ncalls)
 {
        ev->ev_res = res;
        ev->ev_ncalls = ncalls;
+       ev->ev_pncalls = NULL;
        event_queue_insert(ev, EVLIST_ACTIVE);
 }
 
diff --git a/event.h b/event.h
index 03eeb576b286ee9b48019dcccc656fdc8b751ad9..6079f9ad0b1928127d14a6104a2ee020668cb2c3 100644 (file)
--- a/event.h
+++ b/event.h
@@ -78,6 +78,7 @@ struct event {
        int ev_fd;
        short ev_events;
        short ev_ncalls;
+       short *ev_pncalls;      /* Allows deletes in callback */
 
        struct timeval ev_timeout;
 
index afafb44408767968a674bfe93ac9df99503aec25..e89f807fdb91d271961ffe4c7368d68cced7598a 100644 (file)
--- a/select.c
+++ b/select.c
@@ -38,6 +38,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
+#include <err.h>
 
 #ifdef USE_LOG
 #include "log.h"
@@ -68,6 +69,7 @@ struct selectop {
 
 void signal_process(void);
 int signal_recalc(void);
+int signal_deliver(void);
 
 void *select_init      (void);
 int select_add         (void *, struct event *);