[tor-commits] [tor/master] Give control.c responsibility for its own once-a-second events

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


commit 0c19ce7bdece5906e035e71d3fb682632c8bb9cb
Author: Nick Mathewson <nickm at torproject.org>
Date:   Mon May 7 17:41:54 2018 -0400

    Give control.c responsibility for its own once-a-second events
    
    Now it has a function that can tell the rest of Tor whether any
    once-a-second controller item should fire, and a function to fire
    all the once-a-second events.
---
 src/or/control.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/or/control.h |  3 +++
 src/or/main.c    | 19 ++-------------
 3 files changed, 76 insertions(+), 17 deletions(-)

diff --git a/src/or/control.c b/src/or/control.c
index 695f0779c..d653a520b 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1,3 +1,4 @@
+
 /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  * Copyright (c) 2007-2017, The Tor Project, Inc. */
 /* See LICENSE for licensing information */
@@ -112,6 +113,10 @@ static int disable_log_messages = 0;
 #define EVENT_IS_INTERESTING(e) \
   (!! (global_event_mask & EVENT_MASK_(e)))
 
+/** Macro: true if any event from the bitfield 'e' is interesting. */
+#define ANY_EVENT_IS_INTERESTING(e) \
+  EVENT_IS_INTERESTING(e)
+
 /** If we're using cookie-type authentication, how long should our cookies be?
  */
 #define AUTHENTICATION_COOKIE_LEN 32
@@ -219,6 +224,7 @@ static void set_cached_network_liveness(int liveness);
 static void flush_queued_events_cb(mainloop_event_t *event, void *arg);
 
 static char * download_status_to_string(const download_status_t *dl);
+static void control_get_bytes_rw_last_sec(uint64_t *r, uint64_t *w);
 
 /** Given a control event code for a message event, return the corresponding
  * log severity. */
@@ -306,6 +312,10 @@ control_update_global_event_mask(void)
   if (NEWLY_ENABLED(EVENT_CIRC_BANDWIDTH_USED)) {
     clear_circ_bw_fields();
   }
+  if (NEWLY_ENABLED(EVENT_BANDWIDTH_USED)) {
+    uint64_t r, w;
+    control_get_bytes_rw_last_sec(&r, &w);
+  }
 #undef NEWLY_ENABLED
 }
 
@@ -355,6 +365,65 @@ control_event_is_interesting(int event)
   return EVENT_IS_INTERESTING(event);
 }
 
+/** Return true if any event that needs to fire once a second is enabled. */
+int
+control_any_per_second_event_enabled(void)
+{
+  return ANY_EVENT_IS_INTERESTING(
+      EVENT_BANDWIDTH_USED |
+      EVENT_CELL_STATS |
+      EVENT_CIRC_BANDWIDTH_USED |
+      EVENT_CONN_BW |
+      EVENT_STREAM_BANDWIDTH_USED
+  );
+}
+
+/* The value of 'get_bytes_read()' the previous time that
+ * control_get_bytes_rw_last_sec() as called. */
+static uint64_t stats_prev_n_read = 0;
+/* The value of 'get_bytes_written()' the previous time that
+ * control_get_bytes_rw_last_sec() as called. */
+static uint64_t stats_prev_n_written = 0;
+
+/**
+ * Set <b>n_read</b> and <b>n_written</b> to the total number of bytes read
+ * and written by Tor since the last call to this function.
+ *
+ * Call this only from the main thread.
+ */
+static void
+control_get_bytes_rw_last_sec(uint64_t *n_read,
+                              uint64_t *n_written)
+{
+  const uint64_t stats_n_bytes_read = get_bytes_read();
+  const uint64_t stats_n_bytes_written = get_bytes_written();
+
+  *n_read = stats_n_bytes_read - stats_prev_n_read;
+  *n_written = stats_n_bytes_written - stats_prev_n_written;
+  stats_prev_n_read = stats_n_bytes_read;
+  stats_prev_n_written = stats_n_bytes_written;
+}
+
+/**
+ * Run all the controller events (if any) that are scheduled to trigger once
+ * per second.
+ */
+void
+control_per_second_events(void)
+{
+  if (!control_any_per_second_event_enabled())
+    return;
+
+  uint64_t bytes_read, bytes_written;
+  control_get_bytes_rw_last_sec(&bytes_read, &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();
+}
+
 /** Append a NUL-terminated string <b>s</b> to the end of
  * <b>conn</b>-\>outbuf.
  */
@@ -7609,6 +7678,8 @@ control_free_all(void)
 {
   smartlist_t *queued_events = NULL;
 
+  stats_prev_n_read = stats_prev_n_written = 0;
+
   if (authentication_cookie) /* Free the auth cookie */
     tor_free(authentication_cookie);
   if (detached_onion_services) { /* Free the detached onion services */
diff --git a/src/or/control.h b/src/or/control.h
index 7f8a0bdb5..92cbf866d 100644
--- a/src/or/control.h
+++ b/src/or/control.h
@@ -40,6 +40,9 @@ int connection_control_process_inbuf(control_connection_t *conn);
 #define EVENT_NS 0x000F
 int control_event_is_interesting(int event);
 
+void control_per_second_events(void);
+int control_any_per_second_event_enabled(void);
+
 int control_event_circuit_status(origin_circuit_t *circ,
                                  circuit_status_event_t e, int reason);
 int control_event_circuit_purpose_changed(origin_circuit_t *circ,
diff --git a/src/or/main.c b/src/or/main.c
index c3505a2d9..8929931eb 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -163,11 +163,6 @@ token_bucket_rw_t global_bucket;
 /* Token bucket for relayed traffic. */
 token_bucket_rw_t global_relayed_bucket;
 
-/* DOCDOC stats_prev_n_read */
-static uint64_t stats_prev_n_read = 0;
-/* DOCDOC stats_prev_n_written */
-static uint64_t stats_prev_n_written = 0;
-
 /* XXX we might want to keep stats about global_relayed_*_bucket too. Or not.*/
 /** How many bytes have we read since we started the process? */
 static uint64_t stats_n_bytes_read = 0;
@@ -2508,8 +2503,6 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
    * 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;
@@ -2522,16 +2515,9 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
 
   /* the second has rolled over. check more stuff. */
   seconds_elapsed = current_second ? (int)(now - current_second) : 0;
-  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. */
@@ -3651,7 +3637,6 @@ tor_free_all(int postfork)
 
   memset(&global_bucket, 0, sizeof(global_bucket));
   memset(&global_relayed_bucket, 0, sizeof(global_relayed_bucket));
-  stats_prev_n_read = stats_prev_n_written = 0;
   stats_n_bytes_read = stats_n_bytes_written = 0;
   time_of_process_start = 0;
   time_of_last_signewnym = 0;





More information about the tor-commits mailing list