[tor-commits] [tor/master] Merge branch 'ticket26063_squashed'

nickm at torproject.org nickm at torproject.org
Thu May 10 13:13:42 UTC 2018


commit 1eede00a4bd9a7de2acf77393f2fc57aa3196d08
Merge: beca6a585 8b4cf7771
Author: Nick Mathewson <nickm at torproject.org>
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, &current_second_last_changed, sizeof(last_updated));
 +  monotime_coarse_get(&current_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,
 +                                  &current_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



More information about the tor-commits mailing list