diff --git a/src/or/circuit.c b/src/or/circuit.c
index b4eab75c9b2e80eadbee46d6e5c0c2c6a97ba77b..b466e3e4a0ed76193028cd04d48a4fea90144a73 100644
--- a/src/or/circuit.c
+++ b/src/or/circuit.c
@@ -514,6 +514,43 @@ int circuit_stream_is_being_handled(connection_t *conn) {
   return 0;
 }
 
+void circuit_build_needed_circs(time_t now) {
+  static long time_to_new_circuit = 0;
+  circuit_t *circ;
+
+  if (options.SocksPort)
+    /* launch a new circ for any pending streams that need one */
+    connection_ap_attach_pending();
+
+/* Build a new test circuit every 5 minutes */
+#define TESTING_CIRCUIT_INTERVAL 300
+
+  circ = circuit_get_best(NULL, 1, CIRCUIT_PURPOSE_C_GENERAL);
+  if(time_to_new_circuit < now) {
+    client_dns_clean();
+    circuit_expire_unused_circuits();
+    circuit_reset_failure_count();
+    if(circ && circ->timestamp_dirty) {
+      log_fn(LOG_INFO,"Youngest circuit dirty; launching replacement.");
+      /* make a new circuit */
+      circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
+    } else if (options.RunTesting && circ &&
+               circ->timestamp_created + TESTING_CIRCUIT_INTERVAL < now) {
+      log_fn(LOG_INFO,"Creating a new testing circuit.");
+      circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
+    }
+    time_to_new_circuit = now + options.NewCircuitPeriod;
+    time_to_new_circuit = now + options.NewCircuitPeriod;
+  }
+#define CIRCUIT_MIN_BUILDING 3
+  if(!circ && circuit_count_building() < CIRCUIT_MIN_BUILDING) {
+    /* if there's no open circ, and less than 3 are on the way,
+     * go ahead and try another.
+     */
+    circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
+  }
+}
+
 /* update digest from the payload of cell. assign integrity part to cell. */
 static void relay_set_digest(crypto_digest_env_t *digest, cell_t *cell) {
   char integrity[4];
diff --git a/src/or/main.c b/src/or/main.c
index 40a176ecffdfa92adc3a64774264001b11ed8dec..88faede1fa8c2b8a19eb75815e08af39bd099398 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -338,8 +338,6 @@ static void run_connection_housekeeping(int i, time_t now) {
  */
 static void run_scheduled_events(time_t now) {
   static long time_to_fetch_directory = 0;
-  static long time_to_new_circuit = 0;
-  circuit_t *circ;
   int i;
 
   /* 1. Every DirFetchPostPeriod seconds, we get a new directory and upload
@@ -388,49 +386,19 @@ static void run_scheduled_events(time_t now) {
    *    and we make a new circ if there are no clean circuits.
    */
   if(has_fetched_directory &&
-     (options.SocksPort || options.RunTesting)) {
-
-    if (options.SocksPort)
-      /* launch a new circ for any pending streams that need one */
-      connection_ap_attach_pending();
-
-/* Build a new test circuit every 5 minutes */
-#define TESTING_CIRCUIT_INTERVAL 300
-
-    circ = circuit_get_best(NULL, 1, CIRCUIT_PURPOSE_C_GENERAL);
-    if(time_to_new_circuit < now) {
-      client_dns_clean();
-      circuit_expire_unused_circuits();
-      circuit_reset_failure_count();
-      if(circ && circ->timestamp_dirty) {
-        log_fn(LOG_INFO,"Youngest circuit dirty; launching replacement.");
-        /* make a new circuit */
-        circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
-      } else if (options.RunTesting && circ &&
-                 circ->timestamp_created + TESTING_CIRCUIT_INTERVAL < now) {
-        log_fn(LOG_INFO,"Creating a new testing circuit.");
-        circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
-      }
-      time_to_new_circuit = now + options.NewCircuitPeriod;
-    }
-#define CIRCUIT_MIN_BUILDING 3
-    if(!circ && circuit_count_building() < CIRCUIT_MIN_BUILDING) {
-      /* if there's no open circ, and less than 3 are on the way,
-       * go ahead and try another.
-       */
-      circuit_launch_new(CIRCUIT_PURPOSE_C_GENERAL, NULL);
-    }
-  }
+     (options.SocksPort || options.RunTesting))
+    circuit_build_needed_circs(now);
 
-  /* 5. We do housekeeping for each connection... */
+  /* 4. We do housekeeping for each connection... */
   for(i=0;i<nfds;i++) {
     run_connection_housekeeping(i, now);
   }
 
-  /* 6. And remove any marked circuits... */
+  /* 5. And remove any marked circuits... */
   circuit_close_all_marked();
 
-  /* 7. and blow away any connections that need to die. can't do this later
+#if 0
+  /* 6. and blow away any connections that need to die. can't do this later
    * because we might open up a circuit and not realize we're about to cull
    * the connection it's running over.
    * XXX we can remove this step once we audit circuit-building to make sure
@@ -438,6 +406,7 @@ static void run_scheduled_events(time_t now) {
    */
   for(i=0;i<nfds;i++)
     conn_close_if_marked(i);
+#endif
 }
 
 static int prepare_for_poll(void) {
diff --git a/src/or/or.h b/src/or/or.h
index 5d6717b9fafacde563b7b212e57569de7db17eb5..0ddbef0b4a4989323b1de6cf56198e16005dd5d9 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -716,6 +716,7 @@ circuit_t *circuit_get_rendezvous(const char *cookie);
 void circuit_expire_building(void);
 int circuit_count_building(void);
 int circuit_stream_is_being_handled(connection_t *conn);
+void circuit_build_needed_circs(time_t now);
 
 int circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
                                int cell_direction);