Browse Source

Merge remote-tracking branch 'origin/maint-0.2.6'

Nick Mathewson 9 years ago
parent
commit
d8263ac254
2 changed files with 69 additions and 39 deletions
  1. 3 0
      changes/ticket15176
  2. 66 39
      src/or/main.c

+ 3 - 0
changes/ticket15176

@@ -0,0 +1,3 @@
+  o Code simplification and refactoring:
+    - Refactor main loop to extract the 'loop' part.  This makes it easier
+      to run Tor under Shadow. Closes ticket 15176.

+ 66 - 39
src/or/main.c

@@ -97,6 +97,7 @@ static void second_elapsed_callback(periodic_timer_t *timer, void *args);
 static int conn_close_if_marked(int i);
 static void connection_start_reading_from_linked_conn(connection_t *conn);
 static int connection_should_read_from_linked_conn(connection_t *conn);
+static int run_main_loop_until_done(void);
 
 /********* START VARIABLES **********/
 
@@ -1955,7 +1956,6 @@ do_hup(void)
 int
 do_main_loop(void)
 {
-  int loop_result;
   time_t now;
 
   /* initialize dns resolve map, spawn workers if needed */
@@ -2084,51 +2084,78 @@ do_main_loop(void)
   }
 #endif
 
-  for (;;) {
-    if (nt_service_is_stopping())
-      return 0;
+  return run_main_loop_until_done();
+}
+
+/**
+ * Run the main loop a single time. Return 0 for "exit"; -1 for "exit with
+ * error", and 1 for "run this again."
+ */
+static int
+run_main_loop_once(void)
+{
+  int loop_result;
+
+  if (nt_service_is_stopping())
+    return 0;
 
 #ifndef _WIN32
-    /* Make it easier to tell whether libevent failure is our fault or not. */
-    errno = 0;
+  /* Make it easier to tell whether libevent failure is our fault or not. */
+  errno = 0;
 #endif
-    /* All active linked conns should get their read events activated. */
-    SMARTLIST_FOREACH(active_linked_connection_lst, connection_t *, conn,
-                      event_active(conn->read_event, EV_READ, 1));
-    called_loop_once = smartlist_len(active_linked_connection_lst) ? 1 : 0;
-
-    update_approx_time(time(NULL));
-
-    /* poll until we have an event, or the second ends, or until we have
-     * some active linked connections to trigger events for. */
-    loop_result = event_base_loop(tor_libevent_get_base(),
-                                  called_loop_once ? EVLOOP_ONCE : 0);
-
-    /* let catch() handle things like ^c, and otherwise don't worry about it */
-    if (loop_result < 0) {
-      int e = tor_socket_errno(-1);
-      /* let the program survive things like ^z */
-      if (e != EINTR && !ERRNO_IS_EINPROGRESS(e)) {
-        log_err(LD_NET,"libevent call with %s failed: %s [%d]",
-                tor_libevent_get_method(), tor_socket_strerror(e), e);
-        return -1;
+  /* All active linked conns should get their read events activated. */
+  SMARTLIST_FOREACH(active_linked_connection_lst, connection_t *, conn,
+                    event_active(conn->read_event, EV_READ, 1));
+  called_loop_once = smartlist_len(active_linked_connection_lst) ? 1 : 0;
+
+  update_approx_time(time(NULL));
+
+  /* poll until we have an event, or the second ends, or until we have
+   * some active linked connections to trigger events for. */
+  loop_result = event_base_loop(tor_libevent_get_base(),
+                                called_loop_once ? EVLOOP_ONCE : 0);
+
+  /* let catch() handle things like ^c, and otherwise don't worry about it */
+  if (loop_result < 0) {
+    int e = tor_socket_errno(-1);
+    /* let the program survive things like ^z */
+    if (e != EINTR && !ERRNO_IS_EINPROGRESS(e)) {
+      log_err(LD_NET,"libevent call with %s failed: %s [%d]",
+              tor_libevent_get_method(), tor_socket_strerror(e), e);
+      return -1;
 #ifndef _WIN32
-      } else if (e == EINVAL) {
-        log_warn(LD_NET, "EINVAL from libevent: should you upgrade libevent?");
-        if (got_libevent_error())
-          return -1;
+    } else if (e == EINVAL) {
+      log_warn(LD_NET, "EINVAL from libevent: should you upgrade libevent?");
+      if (got_libevent_error())
+        return -1;
 #endif
-      } else {
-        if (ERRNO_IS_EINPROGRESS(e))
-          log_warn(LD_BUG,
-                   "libevent call returned EINPROGRESS? Please report.");
-        log_debug(LD_NET,"libevent call interrupted.");
-        /* You can't trust the results of this poll(). Go back to the
-         * top of the big for loop. */
-        continue;
-      }
+    } else {
+      if (ERRNO_IS_EINPROGRESS(e))
+        log_warn(LD_BUG,
+                 "libevent call returned EINPROGRESS? Please report.");
+      log_debug(LD_NET,"libevent call interrupted.");
+      /* You can't trust the results of this poll(). Go back to the
+       * top of the big for loop. */
+      return 1;
     }
   }
+
+  return 1;
+}
+
+/** Run the run_main_loop_once() function until it declares itself done,
+ * and return its final return value.
+ *
+ * Shadow won't invoke this function, so don't fill it up with things.
+ */
+static int
+run_main_loop_until_done(void)
+{
+  int loop_result = 1;
+  do {
+    loop_result = run_main_loop_once();
+  } while (loop_result == 1);
+  return loop_result;
 }
 
 #ifndef _WIN32 /* Only called when we're willing to use signals */