From 21c562897df3d7453095bd9ae42f2793484712ab Mon Sep 17 00:00:00 2001 From: Niels Provos Date: Sat, 19 Jul 2008 23:41:33 +0000 Subject: [PATCH] from trunk: restore signal handlers correctly when we deallocate the signal base svn:r914 --- ChangeLog | 1 + signal.c | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7cf94db8..9e585324 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ Changes in 1.4.6-stable: o Deal with evbuffer_read() returning -1 on EINTR|EAGAIN; from Adam Langley. o Fix a bug in which the DNS server would incorrectly set the type of a cname reply to a. o Fix a bug where setting the timeout on a bufferevent would take not effect if the event was already pending. + o Fix a memory leak when using signals for some event bases; reported by Alexander Drozdov. Changes in 1.4.5-stable: o Fix connection keep-alive behavior for HTTP/1.0 diff --git a/signal.c b/signal.c index fc4bec84..e36230ad 100644 --- a/signal.c +++ b/signal.c @@ -143,14 +143,19 @@ _evsignal_set_handler(struct event_base *base, * a dynamic array is used to keep footprint on the low side. */ if (evsignal >= sig->sh_old_max) { + int new_max = evsignal + 1; event_debug(("%s: evsignal (%d) >= sh_old_max (%d), resizing", __func__, evsignal, sig->sh_old_max)); - sig->sh_old_max = evsignal + 1; - p = realloc(sig->sh_old, sig->sh_old_max * sizeof *sig->sh_old); + p = realloc(sig->sh_old, new_max * sizeof(*sig->sh_old)); if (p == NULL) { event_warn("realloc"); return (-1); } + + memset((char *)p + sig->sh_old_max * sizeof(*sig->sh_old), + 0, (new_max - sig->sh_old_max) * sizeof(*sig->sh_old)); + + sig->sh_old_max = new_max; sig->sh_old = p; } @@ -326,8 +331,11 @@ evsignal_dealloc(struct event_base *base) event_del(&base->sig.ev_signal); base->sig.ev_signal_added = 0; } - for (i = 0; i < NSIG; ++i) + 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]); base->sig.ev_signal_pair[0] = -1;