[tor-commits] [tor/master] Expose a new function to make the event loop exit once and for all.

nickm at torproject.org nickm at torproject.org
Fri Oct 27 15:15:56 UTC 2017


commit f0c3b6238168e351835fdc64b5c93b84d6528870
Author: Nick Mathewson <nickm at torproject.org>
Date:   Fri Oct 20 10:16:00 2017 -0400

    Expose a new function to make the event loop exit once and for all.
    
    Instead of calling tor_cleanup(), exit(x), we can now call
    tor_shutdown_event_loop_and_exit.
---
 src/common/compat_libevent.h |  1 +
 src/or/main.c                | 47 +++++++++++++++++++++++++++++++++++++++++++-
 src/or/main.h                |  2 ++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/src/common/compat_libevent.h b/src/common/compat_libevent.h
index 834354c40..3d8672fc6 100644
--- a/src/common/compat_libevent.h
+++ b/src/common/compat_libevent.h
@@ -30,6 +30,7 @@ periodic_timer_t *periodic_timer_new(struct event_base *base,
 void periodic_timer_free(periodic_timer_t *);
 
 #define tor_event_base_loopexit event_base_loopexit
+#define tor_event_base_loopbreak event_base_loopbreak
 
 /** Defines a configuration for using libevent with Tor: passed as an argument
  * to tor_libevent_initialize() to describe how we want to set up. */
diff --git a/src/or/main.c b/src/or/main.c
index e3a73ef03..6af61d513 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -192,6 +192,14 @@ static smartlist_t *active_linked_connection_lst = NULL;
  * <b>loop_once</b>. If so, there's no need to trigger a loopexit in order
  * to handle linked connections. */
 static int called_loop_once = 0;
+/** Flag: if true, it's time to shut down, so the main loop should exit as
+ * soon as possible.
+ */
+static int main_loop_should_exit = 0;
+/** The return value that the main loop should yield when it exits, if
+ * main_loop_should_exit is true.
+ */
+static int main_loop_exit_value = 0;
 
 /** We set this to 1 when we've opened a circuit, so we can print a log
  * entry to inform the user that Tor is working.  We set it to 0 when
@@ -648,6 +656,30 @@ tell_event_loop_to_run_external_code(void)
   }
 }
 
+/**
+ * After finishing the current callback (if any), shut down the main loop,
+ * clean up the process, and exit with <b>exitcode</b>.
+ */
+void
+tor_shutdown_event_loop_and_exit(int exitcode)
+{
+  if (main_loop_should_exit)
+    return; /* Ignore multiple calls to this function. */
+
+  main_loop_should_exit = 1;
+  main_loop_exit_value = exitcode;
+
+  /* Unlike loopexit, loopbreak prevents other callbacks from running. */
+  tor_event_base_loopbreak(tor_libevent_get_base());
+}
+
+/** Return true iff tor_shutdown_event_loop_and_exit() has been called. */
+int
+tor_event_loop_shutdown_is_pending(void)
+{
+  return main_loop_should_exit;
+}
+
 /** Helper: Tell the main loop to begin reading bytes into <b>conn</b> from
  * its linked connection, if it is not doing so already.  Called by
  * connection_start_reading and connection_start_writing as appropriate. */
@@ -2595,6 +2627,9 @@ do_main_loop(void)
   }
 #endif /* defined(HAVE_SYSTEMD) */
 
+  main_loop_should_exit = 0;
+  main_loop_exit_value = 0;
+
   return run_main_loop_until_done();
 }
 
@@ -2610,6 +2645,9 @@ run_main_loop_once(void)
   if (nt_service_is_stopping())
     return 0;
 
+  if (main_loop_should_exit)
+    return 0;
+
 #ifndef _WIN32
   /* Make it easier to tell whether libevent failure is our fault or not. */
   errno = 0;
@@ -2656,6 +2694,9 @@ run_main_loop_once(void)
     }
   }
 
+  if (main_loop_should_exit)
+    return 0;
+
   /* And here is where we put callbacks that happen "every time the event loop
    * runs."  They must be very fast, or else the whole Tor process will get
    * slowed down.
@@ -2684,7 +2725,11 @@ run_main_loop_until_done(void)
   do {
     loop_result = run_main_loop_once();
   } while (loop_result == 1);
-  return loop_result;
+
+  if (main_loop_should_exit)
+    return main_loop_exit_value;
+  else
+    return loop_result;
 }
 
 /** Libevent callback: invoked when we get a signal.
diff --git a/src/or/main.h b/src/or/main.h
index 808aa1414..5ab77c03e 100644
--- a/src/or/main.h
+++ b/src/or/main.h
@@ -46,6 +46,8 @@ MOCK_DECL(void,connection_stop_writing,(connection_t *conn));
 MOCK_DECL(void,connection_start_writing,(connection_t *conn));
 
 void tell_event_loop_to_run_external_code(void);
+void tor_shutdown_event_loop_and_exit(int exitcode);
+int tor_event_loop_shutdown_is_pending(void);
 
 void connection_stop_reading_from_linked_conn(connection_t *conn);
 





More information about the tor-commits mailing list