diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-10-20 10:16:00 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-10-20 11:39:17 -0400 |
commit | f0c3b6238168e351835fdc64b5c93b84d6528870 (patch) | |
tree | 1e6a1eacb456a8b60edda037e2e5e426ad5111b7 /src/or/main.c | |
parent | 78cbced45cd244c8aab84e6fb8087b852769f5bc (diff) | |
download | tor-f0c3b6238168e351835fdc64b5c93b84d6528870.tar.gz tor-f0c3b6238168e351835fdc64b5c93b84d6528870.zip |
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.
Diffstat (limited to 'src/or/main.c')
-rw-r--r-- | src/or/main.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/src/or/main.c b/src/or/main.c index e3a73ef03e..6af61d5132 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. |