Browse Source

Use a switch statement and some mild refactoring to try to speed up circuit_expire_building

svn:r5492
Nick Mathewson 20 years ago
parent
commit
61c5a9ae2b
1 changed files with 49 additions and 37 deletions
  1. 49 37
      src/or/circuituse.c

+ 49 - 37
src/or/circuituse.c

@@ -191,16 +191,15 @@ void
 circuit_expire_building(time_t now)
 circuit_expire_building(time_t now)
 {
 {
   circuit_t *victim, *circ = global_circuitlist;
   circuit_t *victim, *circ = global_circuitlist;
+  time_t cutoff = now - MIN_SECONDS_BEFORE_EXPIRING_CIRC;
 
 
   while (circ) {
   while (circ) {
     victim = circ;
     victim = circ;
     circ = circ->next;
     circ = circ->next;
-    if (!CIRCUIT_IS_ORIGIN(victim))
-      continue; /* didn't originate here */
-    if (victim->marked_for_close)
-      continue; /* don't mess with marked circs */
-    if (victim->timestamp_created + MIN_SECONDS_BEFORE_EXPIRING_CIRC > now)
-      continue; /* it's young still, don't mess with it */
+    if (!CIRCUIT_IS_ORIGIN(victim) || /* didn't originate here */
+        victim->timestamp_created > cutoff || /* Not old enough to expire */
+        victim->marked_for_close) /* don't mess with marked circs */
+      continue;
 
 
 #if 0
 #if 0
     /* some debug logs, to help track bugs */
     /* some debug logs, to help track bugs */
@@ -220,40 +219,53 @@ circuit_expire_building(time_t now)
     }
     }
 #endif
 #endif
 
 
+
     /* if circ is !open, or if it's open but purpose is a non-finished
     /* if circ is !open, or if it's open but purpose is a non-finished
      * intro or rend, then mark it for close */
      * intro or rend, then mark it for close */
-    if (victim->state != CIRCUIT_STATE_OPEN ||
-        victim->purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND ||
-        victim->purpose == CIRCUIT_PURPOSE_C_INTRODUCING ||
-        victim->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
-
-        /* it's a rend_ready circ, but it's already picked a query */
-        (victim->purpose == CIRCUIT_PURPOSE_C_REND_READY &&
-         victim->rend_query[0]) ||
-
-        /* c_rend_ready circs measure age since timestamp_dirty,
-         * because that's set when they switch purposes
-         */
-        /* rend and intro circs become dirty each time they
-         * make an introduction attempt. so timestamp_dirty
-         * will reflect the time since the last attempt.
-         */
-        ((victim->purpose == CIRCUIT_PURPOSE_C_REND_READY ||
-          victim->purpose == CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED ||
-          victim->purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) &&
-         victim->timestamp_dirty + MIN_SECONDS_BEFORE_EXPIRING_CIRC > now)) {
-      if (victim->n_conn)
-        info(LD_CIRC,"Abandoning circ %s:%d:%d (state %d:%s, purpose %d)",
-               victim->n_conn->address, victim->n_port, victim->n_circ_id,
-               victim->state, circuit_state_to_string(victim->state), victim->purpose);
-      else
-        info(LD_CIRC,"Abandoning circ %d (state %d:%s, purpose %d)",
-             victim->n_circ_id, victim->state,
-             circuit_state_to_string(victim->state), victim->purpose);
-
-      circuit_log_path(LOG_INFO,LD_CIRC,victim);
-      circuit_mark_for_close(victim);
+    if (victim->state == CIRCUIT_STATE_OPEN) {
+      switch (victim->purpose) {
+        case CIRCUIT_PURPOSE_OR:
+        case CIRCUIT_PURPOSE_INTRO_POINT:
+        case CIRCUIT_PURPOSE_REND_POINT_WAITING:
+        case CIRCUIT_PURPOSE_REND_ESTABLISHED:
+          /* OR-side. We can't actually reach this point because of the
+           * IS_ORIGIN test above. */
+          continue;
+        case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
+        case CIRCUIT_PURPOSE_C_INTRODUCING:
+        case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
+          break;
+        case CIRCUIT_PURPOSE_C_REND_READY:
+          /* it's a rend_ready circ -- has it already picked a query? */
+          if (!victim->rend_query[0] && victim->timestamp_dirty > cutoff)
+            continue;
+          break;
+        case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED:
+        case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT:
+          /* c_rend_ready circs measure age since timestamp_dirty,
+           * because that's set when they switch purposes
+           */
+          /* rend and intro circs become dirty each time they
+           * make an introduction attempt. so timestamp_dirty
+           * will reflect the time since the last attempt.
+           */
+          if (victim->timestamp_dirty > cutoff)
+            continue;
+          break;
+      }
     }
     }
+
+    if (victim->n_conn)
+      info(LD_CIRC,"Abandoning circ %s:%d:%d (state %d:%s, purpose %d)",
+           victim->n_conn->address, victim->n_port, victim->n_circ_id,
+           victim->state, circuit_state_to_string(victim->state), victim->purpose);
+    else
+      info(LD_CIRC,"Abandoning circ %d (state %d:%s, purpose %d)",
+           victim->n_circ_id, victim->state,
+           circuit_state_to_string(victim->state), victim->purpose);
+
+    circuit_log_path(LOG_INFO,LD_CIRC,victim);
+    circuit_mark_for_close(victim);
   }
   }
 }
 }