[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Merge branch 'ticket26063_squashed'
commit 1eede00a4bd9a7de2acf77393f2fc57aa3196d08
Merge: beca6a585 8b4cf7771
Author: Nick Mathewson <nickm@xxxxxxxxxxxxxx>
Date: Thu May 10 09:13:28 2018 -0400
Merge branch 'ticket26063_squashed'
changes/ticket26063 | 5 +++
src/common/compat_libevent.c | 31 ++++++++++++++-
src/common/compat_libevent.h | 2 +
src/or/config.c | 9 +++--
src/or/connection.c | 12 +++---
src/or/connection_edge.c | 1 +
src/or/control.c | 89 ++++++++++++++++++++++++++++++++++++++++++--
src/or/control.h | 3 ++
src/or/dirserv.c | 2 +-
src/or/hibernate.c | 17 ++++++++-
src/or/hibernate.h | 1 +
src/or/main.c | 67 +++++++++++++++++----------------
src/or/main.h | 1 +
src/or/router.c | 18 +++++++--
src/or/router.h | 1 +
15 files changed, 208 insertions(+), 51 deletions(-)
diff --cc src/or/hibernate.c
index b83167d20,24479cff9..d7d259470
--- a/src/or/hibernate.c
+++ b/src/or/hibernate.c
@@@ -1187,18 -1137,10 +1200,20 @@@ on_hibernate_state_change(hibernate_sta
if (prev_state != HIBERNATE_STATE_INITIAL) {
rescan_periodic_events(get_options());
}
+
+ reschedule_per_second_timer();
}
+/** Free all resources held by the accounting module */
+void
+accounting_free_all(void)
+{
+ mainloop_event_free(wakeup_event);
+ hibernate_state = HIBERNATE_STATE_INITIAL;
+ hibernate_end_time = 0;
+ shutdown_time = 0;
+}
+
#ifdef TOR_UNIT_TESTS
/**
* Manually change the hibernation state. Private; used only by the unit
diff --cc src/or/main.c
index 69e7f05b1,0493596aa..6cb9b6249
--- a/src/or/main.c
+++ b/src/or/main.c
@@@ -2495,70 -2491,40 +2491,100 @@@ hs_service_callback(time_t now, const o
/** Timer: used to invoke second_elapsed_callback() once per second. */
static periodic_timer_t *second_timer = NULL;
+
+ /**
+ * Enable or disable the per-second timer as appropriate, creating it if
+ * necessary.
+ */
+ void
+ reschedule_per_second_timer(void)
+ {
+ struct timeval one_second;
+ one_second.tv_sec = 1;
+ one_second.tv_usec = 0;
+
+ if (! second_timer) {
+ second_timer = periodic_timer_new(tor_libevent_get_base(),
+ &one_second,
+ second_elapsed_callback,
+ NULL);
+ tor_assert(second_timer);
+ }
+
+ const bool run_per_second_events =
+ control_any_per_second_event_enabled() || ! net_is_completely_disabled();
+
+ if (run_per_second_events) {
+ periodic_timer_launch(second_timer, &one_second);
+ } else {
+ periodic_timer_disable(second_timer);
+ }
+ }
+
-/** Number of libevent errors in the last second: we die if we get too many. */
-static int n_libevent_errors = 0;
-/** Last time that second_elapsed_callback was called. */
+/** Last time that update_current_time was called. */
static time_t current_second = 0;
+/** Last time that update_current_time updated current_second. */
+static monotime_coarse_t current_second_last_changed;
+
+/**
+ * Set the current time to "now", which should be the value returned by
+ * time(). Check for clock jumps and track the total number of seconds we
+ * have been running.
+ */
+void
+update_current_time(time_t now)
+{
+ if (PREDICT_LIKELY(now == current_second)) {
+ /* We call this function a lot. Most frequently, the current second
+ * will not have changed, so we just return. */
+ return;
+ }
+
+ const time_t seconds_elapsed = current_second ? (now - current_second) : 0;
+
+ /* Check the wall clock against the monotonic clock, so we can
+ * better tell idleness from clock jumps and/or other shenanigans. */
+ monotime_coarse_t last_updated;
+ memcpy(&last_updated, ¤t_second_last_changed, sizeof(last_updated));
+ monotime_coarse_get(¤t_second_last_changed);
+
+ /** How much clock jumping do we tolerate? */
+#define NUM_JUMPED_SECONDS_BEFORE_WARN 100
+
+ /** How much idleness do we tolerate? */
+#define NUM_IDLE_SECONDS_BEFORE_WARN 3600
+
+ if (seconds_elapsed < -NUM_JUMPED_SECONDS_BEFORE_WARN) {
+ // moving back in time is always a bad sign.
+ circuit_note_clock_jumped(seconds_elapsed, false);
+ } else if (seconds_elapsed >= NUM_JUMPED_SECONDS_BEFORE_WARN) {
+ /* Compare the monotonic clock to the result of time(). */
+ const int32_t monotime_msec_passed =
+ monotime_coarse_diff_msec32(&last_updated,
+ ¤t_second_last_changed);
+ const int monotime_sec_passed = monotime_msec_passed / 1000;
+ const int discrepancy = monotime_sec_passed - (int)seconds_elapsed;
+ /* If the monotonic clock deviates from time(NULL), we have a couple of
+ * possibilities. On some systems, this means we have been suspended or
+ * sleeping. Everywhere, it can mean that the wall-clock time has
+ * been changed -- for example, with settimeofday().
+ *
+ * On the other hand, if the monotonic time matches with the wall-clock
+ * time, we've probably just been idle for a while, with no events firing.
+ * we tolerate much more of that.
+ */
+ const bool clock_jumped = abs(discrepancy) > 2;
+
+ if (clock_jumped || seconds_elapsed >= NUM_IDLE_SECONDS_BEFORE_WARN) {
+ circuit_note_clock_jumped(seconds_elapsed, ! clock_jumped);
+ }
+ } else if (seconds_elapsed > 0) {
+ stats_n_seconds_working += seconds_elapsed;
+ }
+
+ update_approx_time(now);
+ current_second = now;
+}
/** Libevent callback: invoked once every second. */
static void
@@@ -2568,33 -2534,34 +2594,21 @@@ second_elapsed_callback(periodic_timer_
* could use Libevent's timers for this rather than checking the current
* time against a bunch of timeouts every second. */
time_t now;
- size_t bytes_written;
- size_t bytes_read;
- int seconds_elapsed;
(void)timer;
(void)arg;
- n_libevent_errors = 0;
-
- /* log_notice(LD_GENERAL, "Tick."); */
now = time(NULL);
- update_approx_time(now);
- /* the second has rolled over. check more stuff. */
- seconds_elapsed = current_second ? (int)(now - current_second) : 0;
+ /* We don't need to do this once-per-second any more: time-updating is
+ * only in this callback _because it is a callback_. It should be fine
+ * to disable this callback, and the time will still get updated.
+ */
+ update_current_time(now);
- /* the second has rolled over. check more stuff. */
- // remove this once it's unneeded
- bytes_read = (size_t)(stats_n_bytes_read - stats_prev_n_read);
- bytes_written = (size_t)(stats_n_bytes_written - stats_prev_n_written);
- stats_prev_n_read = stats_n_bytes_read;
- stats_prev_n_written = stats_n_bytes_written;
-
- control_event_bandwidth_used((uint32_t)bytes_read,(uint32_t)bytes_written);
- control_event_stream_bandwidth_used();
- control_event_conn_bandwidth_used();
- control_event_circ_bandwidth_used();
- control_event_circuit_cell_stats();
+ /* Maybe some controller events are ready to fire */
+ control_per_second_events();
-/** If more than this many seconds have elapsed, probably the clock
- * jumped: doesn't count. */
-#define NUM_JUMPED_SECONDS_BEFORE_WARN 100
- if (seconds_elapsed < -NUM_JUMPED_SECONDS_BEFORE_WARN ||
- seconds_elapsed >= NUM_JUMPED_SECONDS_BEFORE_WARN) {
- circuit_note_clock_jumped(seconds_elapsed);
- } else if (seconds_elapsed > 0)
- stats_n_seconds_working += seconds_elapsed;
-
run_scheduled_events(now);
-
- current_second = now; /* remember which second it is, for next time */
}
#ifdef HAVE_SYSTEMD_209
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits