diff options
author | Nick Mathewson <nickm@torproject.org> | 2018-05-03 11:57:09 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2018-05-03 11:57:09 -0400 |
commit | be9f0e5f20e37d2176ce0663b71b532c44c10c28 (patch) | |
tree | 28efed8b00bca7b4dd9054028b7a5bf0b7ce43dd | |
parent | 319505d38c459ad446caefec5446d717c2d9e4e6 (diff) | |
parent | 57f557747d7d357e3b7190070f648887831f10a0 (diff) | |
download | tor-be9f0e5f20e37d2176ce0663b71b532c44c10c28.tar.gz tor-be9f0e5f20e37d2176ce0663b71b532c44c10c28.zip |
Merge remote-tracking branch 'github/ticket25949'
-rw-r--r-- | changes/ticket25949 | 9 | ||||
-rw-r--r-- | src/or/main.c | 37 |
2 files changed, 35 insertions, 11 deletions
diff --git a/changes/ticket25949 b/changes/ticket25949 new file mode 100644 index 0000000000..fd87373418 --- /dev/null +++ b/changes/ticket25949 @@ -0,0 +1,9 @@ + o Minor features (mainloop): + - Move responsibility for + honoring delayed SIGNEWNYM requests + from a once-per-second callback to a callback that is only scheduled as + needed. Once enough items are removed from our once-per-second + callback, we can eliminate it entirely to conserve CPU when idle. + Closes ticket + 25949. + diff --git a/src/or/main.c b/src/or/main.c index cf0df9ba79..b492166f87 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -188,6 +188,8 @@ static uint64_t stats_n_main_loop_idle = 0; static time_t time_of_last_signewnym = 0; /** Is there a signewnym request we're currently waiting to handle? */ static int signewnym_is_pending = 0; +/** Mainloop event for the deferred signewnym call. */ +static mainloop_event_t *handle_deferred_signewnym_ev = NULL; /** How many times have we called newnym? */ static unsigned newnym_epoch = 0; @@ -1316,6 +1318,16 @@ signewnym_impl(time_t now) control_event_signal(SIGNEWNYM); } +/** Callback: run a deferred signewnym. */ +static void +handle_deferred_signewnym_cb(mainloop_event_t *event, void *arg) +{ + (void)event; + (void)arg; + log_info(LD_CONTROL, "Honoring delayed NEWNYM request"); + signewnym_impl(time(NULL)); +} + /** Return the number of times that signewnym has been called. */ unsigned get_signewnym_epoch(void) @@ -1699,14 +1711,6 @@ run_scheduled_events(time_t now) */ consider_hibernation(now); - /* 0b. If we've deferred a signewnym, make sure it gets handled - * eventually. */ - if (signewnym_is_pending && - time_of_last_signewnym + MAX_SIGNEWNYM_RATE <= now) { - log_info(LD_CONTROL, "Honoring delayed NEWNYM request"); - signewnym_impl(now); - } - /* 0c. If we've deferred log messages for the controller, handle them now */ flush_pending_log_callbacks(); @@ -3075,10 +3079,20 @@ process_signal(int sig) case SIGNEWNYM: { time_t now = time(NULL); if (time_of_last_signewnym + MAX_SIGNEWNYM_RATE > now) { - signewnym_is_pending = 1; + const time_t delay_sec = + time_of_last_signewnym + MAX_SIGNEWNYM_RATE - now; + if (! signewnym_is_pending) { + signewnym_is_pending = 1; + if (!handle_deferred_signewnym_ev) { + handle_deferred_signewnym_ev = + mainloop_event_postloop_new(handle_deferred_signewnym_cb, NULL); + } + const struct timeval delay_tv = { delay_sec, 0 }; + mainloop_event_schedule(handle_deferred_signewnym_ev, &delay_tv); + } log_notice(LD_CONTROL, - "Rate limiting NEWNYM request: delaying by %d second(s)", - (int)(MAX_SIGNEWNYM_RATE+time_of_last_signewnym-now)); + "Rate limiting NEWNYM request: delaying by %d second(s)", + (int)(delay_sec)); } else { signewnym_impl(now); } @@ -3617,6 +3631,7 @@ tor_free_all(int postfork) mainloop_event_free(directory_all_unreachable_cb_event); mainloop_event_free(schedule_active_linked_connections_event); mainloop_event_free(postloop_cleanup_ev); + mainloop_event_free(handle_deferred_signewnym_ev); #ifdef HAVE_SYSTEMD_209 periodic_timer_free(systemd_watchdog_timer); |