Bläddra i källkod

Merge branch 'ticket25948_squashed'

Nick Mathewson 6 år sedan
förälder
incheckning
72124dc1ef
7 ändrade filer med 63 tillägg och 16 borttagningar
  1. 9 0
      changes/ticket25948
  2. 38 6
      src/or/main.c
  3. 1 0
      src/or/main.h
  4. 0 9
      src/or/or.h
  5. 1 1
      src/or/rephist.c
  6. 13 0
      src/or/statefile.c
  7. 1 0
      src/or/statefile.h

+ 9 - 0
changes/ticket25948

@@ -0,0 +1,9 @@
+  o Minor features (mainloop):
+    - Move responsibility for
+      saving the state file to disk
+      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
+      25948.
+

+ 38 - 6
src/or/main.c

@@ -1355,6 +1355,7 @@ CALLBACK(retry_listeners);
 CALLBACK(rotate_onion_key);
 CALLBACK(rotate_x509_certificate);
 CALLBACK(save_stability);
+CALLBACK(save_state);
 CALLBACK(write_bridge_ns);
 CALLBACK(write_stats_file);
 
@@ -1376,6 +1377,7 @@ STATIC periodic_event_item_t periodic_events[] = {
   CALLBACK(reset_padding_counts, PERIODIC_EVENT_ROLE_ALL, 0),
   CALLBACK(retry_listeners, PERIODIC_EVENT_ROLE_ALL,
            PERIODIC_EVENT_FLAG_NEED_NET),
+  CALLBACK(save_state, PERIODIC_EVENT_ROLE_ALL, 0),
   CALLBACK(rotate_x509_certificate, PERIODIC_EVENT_ROLE_ALL, 0),
   CALLBACK(write_stats_file, PERIODIC_EVENT_ROLE_ALL, 0),
 
@@ -1434,6 +1436,7 @@ static periodic_event_item_t *check_descriptor_event=NULL;
 static periodic_event_item_t *fetch_networkstatus_event=NULL;
 static periodic_event_item_t *launch_descriptor_fetches_event=NULL;
 static periodic_event_item_t *check_dns_honesty_event=NULL;
+static periodic_event_item_t *save_state_event=NULL;
 
 /** Reset all the periodic events so we'll do all our actions again as if we
  * just started up.
@@ -1532,6 +1535,7 @@ initialize_periodic_events(void)
   NAMED_CALLBACK(fetch_networkstatus);
   NAMED_CALLBACK(launch_descriptor_fetches);
   NAMED_CALLBACK(check_dns_honesty);
+  NAMED_CALLBACK(save_state);
 
   struct timeval one_second = { 1, 0 };
   initialize_periodic_events_event = tor_evtimer_new(
@@ -1609,8 +1613,9 @@ periodic_events_on_new_options(const or_options_t *options)
 void
 reschedule_descriptor_update_check(void)
 {
-  tor_assert(check_descriptor_event);
-  periodic_event_reschedule(check_descriptor_event);
+  if (check_descriptor_event) {
+    periodic_event_reschedule(check_descriptor_event);
+  }
 }
 
 /**
@@ -1756,10 +1761,6 @@ run_scheduled_events(time_t now)
     run_connection_housekeeping(i, now);
   }
 
-  /* 8b. And if anything in our state is ready to get flushed to disk, we
-   * flush it. */
-  or_state_save(now);
-
   /* 11b. check pending unconfigured managed proxies */
   if (!net_is_disabled() && pt_proxies_configuration_pending())
     pt_configure_remaining_proxies();
@@ -1993,6 +1994,37 @@ check_expired_networkstatus_callback(time_t now, const or_options_t *options)
   return CHECK_EXPIRED_NS_INTERVAL;
 }
 
+/**
+ * Scheduled callback: Save the state file to disk if appropriate.
+ */
+static int
+save_state_callback(time_t now, const or_options_t *options)
+{
+  (void) options;
+  (void) or_state_save(now); // only saves if appropriate
+  const time_t next_write = get_or_state()->next_write;
+  if (next_write == TIME_MAX) {
+    return 86400;
+  } else if (BUG(next_write <= now)) {
+    /* This can't happen due to clock jumps, since the value of next_write
+     * is based on the same "now" that we passed to or_state_save().
+     */
+    return PERIODIC_EVENT_NO_UPDATE;
+  } else {
+    return next_write - now;
+  }
+}
+
+/** Reschedule the event for saving the state file.
+ *
+ * Run this when the state becomes dirty. */
+void
+reschedule_or_state_save(void)
+{
+  tor_assert(save_state_event);
+  periodic_event_reschedule(save_state_event);
+}
+
 /**
  * Periodic callback: Write statistics to disk if appropriate.
  */

+ 1 - 0
src/or/main.h

@@ -61,6 +61,7 @@ void dns_servers_relaunch_checks(void);
 void reset_all_main_loop_timers(void);
 void reschedule_descriptor_update_check(void);
 void reschedule_directory_downloads(void);
+void reschedule_or_state_save(void);
 void mainloop_schedule_postloop_cleanup(void);
 void rescan_periodic_events(const or_options_t *options);
 

+ 0 - 9
src/or/or.h

@@ -4746,15 +4746,6 @@ typedef struct {
   time_t LastRotatedOnionKey;
 } or_state_t;
 
-/** Change the next_write time of <b>state</b> to <b>when</b>, unless the
- * state is already scheduled to be written to disk earlier than <b>when</b>.
- */
-static inline void or_state_mark_dirty(or_state_t *state, time_t when)
-{
-  if (state->next_write > when)
-    state->next_write = when;
-}
-
 #define MAX_SOCKS_REPLY_LEN 1024
 #define MAX_SOCKS_ADDR_LEN 256
 #define SOCKS_NO_AUTH 0x00

+ 1 - 1
src/or/rephist.c

@@ -85,8 +85,8 @@
 #include "routerlist.h"
 #include "ht.h"
 #include "channelpadding.h"
-
 #include "connection_or.h"
+#include "statefile.h"
 
 static void bw_arrays_init(void);
 static void predicted_ports_alloc(void);

+ 13 - 0
src/or/statefile.c

@@ -37,6 +37,7 @@
 #include "control.h"
 #include "entrynodes.h"
 #include "hibernate.h"
+#include "main.h"
 #include "rephist.h"
 #include "router.h"
 #include "sandbox.h"
@@ -680,6 +681,18 @@ save_transport_to_state(const char *transport,
   tor_free(transport_addrport);
 }
 
+/** Change the next_write time of <b>state</b> to <b>when</b>, unless the
+ * state is already scheduled to be written to disk earlier than <b>when</b>.
+ */
+void
+or_state_mark_dirty(or_state_t *state, time_t when)
+{
+  if (state->next_write > when) {
+    state->next_write = when;
+    reschedule_or_state_save();
+  }
+}
+
 STATIC void
 or_state_free_(or_state_t *state)
 {

+ 1 - 0
src/or/statefile.h

@@ -17,6 +17,7 @@ char *get_stored_bindaddr_for_server_transport(const char *transport);
 int or_state_load(void);
 int or_state_loaded(void);
 void or_state_free_all(void);
+void or_state_mark_dirty(or_state_t *state, time_t when);
 
 #ifdef STATEFILE_PRIVATE
 STATIC config_line_t *get_transport_in_state_by_name(const char *transport);