[tor-commits] [tor/master] Stop using event_base_once().
nickm at torproject.org
nickm at torproject.org
Thu Jan 11 17:31:47 UTC 2018
commit f205dabf7ae5c8dde9adc3cc39ef7721953abfea
Author: Nick Mathewson <nickm at torproject.org>
Date: Mon Dec 11 12:21:00 2017 -0500
Stop using event_base_once().
This function leaks memory when the event_base is freed before the
event itself fires. That's not harmful, but it's annoying when
trying to debug other memory leaks.
Fixes bug 24584; bugfix on 0.2.8.1-alpha.
---
changes/bug24584 | 5 +++++
src/or/main.c | 22 ++++++++++++++++------
2 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/changes/bug24584 b/changes/bug24584
new file mode 100644
index 000000000..071c7c2a1
--- /dev/null
+++ b/changes/bug24584
@@ -0,0 +1,5 @@
+ o Minor bugfixes (memory cleanup):
+ - Avoid possible at-exit memory leaks related to use of Libevent's
+ event_base_once() function. (This function tends to leak memory
+ if the event_base is closed before the event fires.) Fixes bug 24584;
+ bugfix on 0.2.8.1-alpha.
diff --git a/src/or/main.c b/src/or/main.c
index aae98dd8a..6d58cf341 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -666,6 +666,9 @@ tell_event_loop_to_run_external_code(void)
}
}
+/** Event to run 'shutdown did not work callback'. */
+static struct event *shutdown_did_not_work_event = NULL;
+
/** Failsafe measure that should never actually be necessary: If
* tor_shutdown_event_loop_and_exit() somehow doesn't successfully exit the
* event loop, then this callback will kill Tor with an assertion failure
@@ -699,9 +702,10 @@ tor_shutdown_event_loop_and_exit(int exitcode)
* exit normally. */
/* XXXX We should consider this code if it's never used. */
struct timeval ten_seconds = { 10, 0 };
- event_base_once(tor_libevent_get_base(), -1, EV_TIMEOUT,
- shutdown_did_not_work_callback, NULL,
- &ten_seconds);
+ shutdown_did_not_work_event = tor_evtimer_new(
+ tor_libevent_get_base(),
+ shutdown_did_not_work_callback, NULL);
+ event_add(shutdown_did_not_work_event, &ten_seconds);
/* Unlike loopexit, loopbreak prevents other callbacks from running. */
tor_event_base_loopbreak(tor_libevent_get_base());
@@ -1341,6 +1345,8 @@ find_periodic_event(const char *name)
return NULL;
}
+/** Event to run initialize_periodic_events_cb */
+static struct event *initialize_periodic_events_event = NULL;
/** Helper, run one second after setup:
* Initializes all members of periodic_events and starts them running.
*
@@ -1352,6 +1358,7 @@ initialize_periodic_events_cb(evutil_socket_t fd, short events, void *data)
(void) fd;
(void) events;
(void) data;
+ tor_event_free(initialize_periodic_events_event);
int i;
for (i = 0; periodic_events[i].name; ++i) {
periodic_event_launch(&periodic_events[i]);
@@ -1380,9 +1387,10 @@ initialize_periodic_events(void)
NAMED_CALLBACK(check_dns_honesty);
struct timeval one_second = { 1, 0 };
- event_base_once(tor_libevent_get_base(), -1, EV_TIMEOUT,
- initialize_periodic_events_cb, NULL,
- &one_second);
+ initialize_periodic_events_event = tor_evtimer_new(
+ tor_libevent_get_base(),
+ initialize_periodic_events_cb, NULL);
+ event_add(initialize_periodic_events_event, &one_second);
}
STATIC void
@@ -3384,6 +3392,8 @@ tor_free_all(int postfork)
periodic_timer_free(second_timer);
teardown_periodic_events();
periodic_timer_free(refill_timer);
+ tor_event_free(shutdown_did_not_work_event);
+ tor_event_free(initialize_periodic_events_event);
if (!postfork) {
release_lockfile();
More information about the tor-commits
mailing list