Browse Source

Reduced required locking when processing inbuf

Steven Engler 4 years ago
parent
commit
79bf854c32
1 changed files with 23 additions and 12 deletions
  1. 23 12
      src/core/or/safe_connection.c

+ 23 - 12
src/core/or/safe_connection.c

@@ -596,6 +596,11 @@ safe_or_connection_new(bool requires_buffers, bool is_outgoing,
                            or_conn_outgoing_variable_cell);
   }
 
+  event_source_deliver_silently(TO_SAFE_CONN(safe_or_conn)->event_source,
+                                safe_or_conn_var_cell_ev, true);
+  event_source_deliver_silently(TO_SAFE_CONN(safe_or_conn)->event_source,
+                                safe_or_conn_fixed_cell_ev, true);
+
   safe_or_conn->link_protocol = 0; // unknown protocol
   safe_or_conn->wide_circ_ids = false;
   safe_or_conn->waiting_for_link_protocol = false;
@@ -1789,21 +1794,21 @@ process_cells_from_inbuf(safe_or_connection_t *safe_or_conn)
   tor_assert(safe_or_conn != NULL);
   tor_assert(safe_or_conn->waiting_for_link_protocol == false);
 
-  event_source_deliver_silently(TO_SAFE_CONN(safe_or_conn)->event_source,
-                                safe_or_conn_var_cell_ev, true);
-  event_source_deliver_silently(TO_SAFE_CONN(safe_or_conn)->event_source,
-                                safe_or_conn_fixed_cell_ev, true);
+  bool found_var_cell = false;
+  bool found_fixed_cell = false;
 
   while (true) {
     var_cell_t *var_cell = NULL;
-    bool found_var_cell = fetch_var_cell(safe_or_conn, &var_cell);
+    bool next_is_var_cell = fetch_var_cell(safe_or_conn, &var_cell);
 
-    if (found_var_cell) {
+    if (next_is_var_cell) {
       if (var_cell == NULL) {
         // the next cell is a var cell, but it is not yet complete
         break;
       }
 
+      found_var_cell = true;
+
       uint8_t command = var_cell->command;
 
       event_data_t event_data = { .ptr = var_cell };
@@ -1822,9 +1827,11 @@ process_cells_from_inbuf(safe_or_connection_t *safe_or_conn)
       }
     } else {
       char buf[CELL_MAX_NETWORK_SIZE];
-      bool found_cell = fetch_cell(safe_or_conn, buf);
+      bool next_is_fixed_cell = fetch_cell(safe_or_conn, buf);
+
+      if (next_is_fixed_cell) {
+        found_fixed_cell = true;
 
-      if (found_cell) {
         // retrieve cell info from buf (create the host-order struct from the
         // network-order string)
         cell_t *cell = tor_malloc(sizeof(cell_t));
@@ -1843,8 +1850,12 @@ process_cells_from_inbuf(safe_or_connection_t *safe_or_conn)
     }
   }
 
-  event_source_wakeup_listener(TO_SAFE_CONN(safe_or_conn)->event_source,
-                               safe_or_conn_var_cell_ev);
-  event_source_wakeup_listener(TO_SAFE_CONN(safe_or_conn)->event_source,
-                               safe_or_conn_fixed_cell_ev);
+  if (found_var_cell) {
+    event_source_wakeup_listener(TO_SAFE_CONN(safe_or_conn)->event_source,
+                                 safe_or_conn_var_cell_ev);
+  }
+  if (found_fixed_cell) {
+    event_source_wakeup_listener(TO_SAFE_CONN(safe_or_conn)->event_source,
+                                 safe_or_conn_fixed_cell_ev);
+  }
 }