]> granicus.if.org Git - libevent/commitdiff
fix a problem with epoll and event_reinit; reported by Alexander Drozdov
authorNiels Provos <provos@gmail.com>
Fri, 25 Jul 2008 00:19:15 +0000 (00:19 +0000)
committerNiels Provos <provos@gmail.com>
Fri, 25 Jul 2008 00:19:15 +0000 (00:19 +0000)
svn:r917

ChangeLog
event.c
signal.c

index 3217fe49f2a2842923563ef927c5823a980826db..34def8286c1559a92d5df19dd629b7e7e730cabb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -118,7 +118,7 @@ Changes in current version:
  o Various HTTP correctness fixes from Scott Lamb
  o Fix a bug where deleting signals with the kqueue backend would cause subsequent adds to fail
  o Support multiple events listening on the same signal; make signals regular events that go on the same event queue; problem report by Alexander Drozdov.
-       
+ o Fix a problem with epoll() and reinit; problem report by Alexander Drozdov. 
 Changes in 1.4.0:
  o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
  o demote most http warnings to debug messages
diff --git a/event.c b/event.c
index bc307344b33c20704d59999dbe46d77fef2d4cde..a5a4223405a0265765564a9eebbda002c9292516 100644 (file)
--- a/event.c
+++ b/event.c
@@ -328,9 +328,20 @@ event_base_free(struct event_base *base)
                ++n_deleted;
        }
 
+       for (i = 0; i < base->nactivequeues; ++i) {
+               for (ev = TAILQ_FIRST(base->activequeues[i]); ev; ) {
+                       struct event *next = TAILQ_NEXT(ev, ev_active_next);
+                       if (!(ev->ev_flags & EVLIST_INTERNAL)) {
+                               event_del(ev);
+                               ++n_deleted;
+                       }
+                       ev = next;
+               }
+       }
+
        if (n_deleted)
                event_debug(("%s: %d events were still set in base",
-                                        __func__, n_deleted));
+                       __func__, n_deleted));
 
        if (base->evsel->dealloc != NULL)
                base->evsel->dealloc(base, base->evbase);
@@ -363,6 +374,10 @@ event_reinit(struct event_base *base)
        if (!evsel->need_reinit)
                return (0);
 
+       /* prevent internal delete */
+       if (base->sig.ev_signal_added)
+               base->sig.ev_signal_added = 0;
+       
        if (base->evsel->dealloc != NULL)
                base->evsel->dealloc(base, base->evbase);
        evbase = base->evbase = evsel->init(base);
index 01b38b26cf771407b890b4af6305c061596dfb71..a5a329ebc04f3dd84699da35bba962ba8e3646db 100644 (file)
--- a/signal.c
+++ b/signal.c
@@ -335,7 +335,6 @@ evsignal_dealloc(struct event_base *base)
        for (i = 0; i < NSIG; ++i) {
                if (i < base->sig.sh_old_max && base->sig.sh_old[i] != NULL)
                        _evsignal_restore_handler(base, i);
-               assert(TAILQ_EMPTY(&base->sig.evsigevents[0]));
        }
 
        EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]);