]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Stop using event_base_once().
authorNick Mathewson <nickm@torproject.org>
Mon, 11 Dec 2017 17:21:00 +0000 (12:21 -0500)
committerNick Mathewson <nickm@torproject.org>
Mon, 11 Dec 2017 17:23:02 +0000 (12:23 -0500)
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 [new file with mode: 0644]
src/or/main.c

diff --git a/changes/bug24584 b/changes/bug24584
new file mode 100644 (file)
index 0000000..071c7c2
--- /dev/null
@@ -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.
index aae98dd8abde25fb7f03d2148a5ca01496a6780f..6d58cf34177209d1cf1f4fe40bd1919b6720e1fb 100644 (file)
@@ -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();