mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-06 18:58:09 -04:00
r16497@catbus: nickm | 2007-11-07 00:01:02 -0500
Resolve issue 1826588: make event_base_free() succeed even if there are pending non-INTERNAL events still in the base. This can leak memory and fds if used injudiciously, but at least it no longer crashes. svn:r490
This commit is contained in:
parent
29420339dc
commit
206d433638
@ -40,4 +40,4 @@ Changes in current version:
|
||||
o Remove support for the rtsig method: it hasn't compiled for a while, and nobody seems to miss it very much. Let us know if there's a good reason to put it back in.
|
||||
o Rename the "class" field in evdns_server_request to dns_question_class, so that it won't break compilation under C++. Use a macro so that old code won't break. Mark the macro as deprecated.
|
||||
o Fix DNS unit tests so that having a DNS server with broken IPv6 support is no longer cause for aborting the unit tests.
|
||||
|
||||
o Make event_base_free() succeed even if there are pending non-internal events on a base. This may still leak memory and fds, but at least it no longer crashes.
|
||||
|
19
event.c
19
event.c
@ -199,17 +199,32 @@ event_init(void)
|
||||
void
|
||||
event_base_free(struct event_base *base)
|
||||
{
|
||||
int i;
|
||||
int i, n_deleted=0;
|
||||
struct event *ev;
|
||||
|
||||
if (base == NULL && current_base)
|
||||
base = current_base;
|
||||
if (base == current_base)
|
||||
if (base == current_base)
|
||||
current_base = NULL;
|
||||
|
||||
/* XXX(niels) - check for internal events first */
|
||||
assert(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;
|
||||
}
|
||||
if (n_deleted)
|
||||
event_debug(("%s: %d events were still set in base",
|
||||
__func__, n_deleted));
|
||||
|
||||
if (base->evsel->dealloc != NULL)
|
||||
base->evsel->dealloc(base, base->evbase);
|
||||
|
||||
for (i=0; i < base->nactivequeues; ++i)
|
||||
assert(TAILQ_EMPTY(base->activequeues[i]));
|
||||
assert(min_heap_empty(&base->timeheap));
|
||||
|
@ -557,6 +557,22 @@ test_signal_switchbase(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
test_free_active_base(void)
|
||||
{
|
||||
struct event_base *base1;
|
||||
struct event ev1;
|
||||
setup_test("Free active base: ");
|
||||
base1 = event_init();
|
||||
event_set(&ev1, pair[1], EV_READ, simple_read_cb, &ev1);
|
||||
event_base_set(base1, &ev1);
|
||||
event_add(&ev1, NULL);
|
||||
/* event_del(&ev1); */
|
||||
event_base_free(base1);
|
||||
test_ok = 1;
|
||||
cleanup_test();
|
||||
}
|
||||
|
||||
void
|
||||
test_loopexit(void)
|
||||
{
|
||||
@ -1063,6 +1079,8 @@ main (int argc, char **argv)
|
||||
|
||||
test_bufferevent();
|
||||
|
||||
test_free_active_base();
|
||||
|
||||
http_suite();
|
||||
|
||||
rpc_suite();
|
||||
|
Loading…
x
Reference in New Issue
Block a user