Pārlūkot izejas kodu

Add kludgy function to force controllers to flush EVENT_ERR_MSG events.

svn:r4057
Nick Mathewson 20 gadi atpakaļ
vecāks
revīzija
74dc7eedc5
3 mainītis faili ar 38 papildinājumiem un 0 dzēšanām
  1. 34 0
      src/or/connection.c
  2. 3 0
      src/or/control.c
  3. 1 0
      src/or/or.h

+ 34 - 0
src/or/connection.c

@@ -1265,6 +1265,40 @@ int connection_handle_write(connection_t *conn) {
   return 0;
 }
 
+/* DOCDOC */
+void _connection_controller_force_write(connection_t *conn)
+{
+  /* XXX This is hideous code duplication, but raising it seems a little
+   * tricky for now.  Think more about this one.   We only call it for
+   * EVENT_ERR_MSG, so messing with buckets a little isn't such a big problem.
+   */
+  int result;
+  tor_assert(conn);
+  tor_assert(!conn->tls);
+  tor_assert(conn->type == CONN_TYPE_CONTROL);
+  if (conn->marked_for_close || conn->s < 0)
+    return;
+
+  result = flush_buf(conn->s, conn->outbuf, &conn->outbuf_flushlen);
+  if (result < 0) {
+    connection_close_immediate(conn); /* Don't flush; connection is dead. */
+    connection_mark_for_close(conn);
+    return;
+  }
+
+  if (result > 0 && !is_local_IP(conn->addr)) { /* remember it */
+    rep_hist_note_bytes_written(result, time(NULL));
+    global_write_bucket -= result;
+  }
+
+  if (!connection_wants_to_flush(conn)) { /* it's done flushing */
+    if (connection_finished_flushing(conn) < 0) {
+      /* already marked */
+      return;
+    }
+  }
+}
+
 /** Append <b>len</b> bytes of <b>string</b> onto <b>conn</b>'s
  * outbuf, and ask it to start writing.
  */

+ 3 - 0
src/or/control.c

@@ -330,6 +330,9 @@ send_control_event(uint16_t event, uint32_t len, const char *body)
         conns[i]->state == CONTROL_CONN_STATE_OPEN &&
         conns[i]->event_mask & (1<<event)) {
       send_control_message(conns[i], CONTROL_CMD_EVENT, buflen, buf);
+      if (event == EVENT_ERR_MSG) {
+        _connection_controller_force_write(conns[i]);
+      }
     }
   }
 

+ 1 - 0
src/or/or.h

@@ -1283,6 +1283,7 @@ int connection_fetch_from_buf(char *string, size_t len, connection_t *conn);
 int connection_wants_to_flush(connection_t *conn);
 int connection_outbuf_too_full(connection_t *conn);
 int connection_handle_write(connection_t *conn);
+void _connection_controller_force_write(connection_t *conn);
 void connection_write_to_buf(const char *string, size_t len, connection_t *conn);
 
 connection_t *connection_or_exact_get_by_addr_port(uint32_t addr, uint16_t port);