Move connection_ap_attach_pending(0) into a postloop event

This is a second motivating case for our postloop event logic.
This commit is contained in:
Nick Mathewson 2018-04-02 15:20:21 -04:00
parent 5719dfb48f
commit 320bd2b3a5
2 changed files with 22 additions and 23 deletions

View File

@ -611,6 +611,12 @@ static smartlist_t *pending_entry_connections = NULL;
static int untried_pending_connections = 0;
/**
* Mainloop event to tell us to scan for pending connections that can
* be attached.
*/
static mainloop_event_t *attach_pending_entry_connections_ev = NULL;
/** Common code to connection_(ap|exit)_about_to_close. */
static void
connection_edge_about_to_close(edge_connection_t *edge_conn)
@ -956,6 +962,14 @@ connection_ap_attach_pending(int retry)
untried_pending_connections = 0;
}
static void
attach_pending_entry_connections_cb(mainloop_event_t *ev, void *arg)
{
(void)ev;
(void)arg;
connection_ap_attach_pending(0);
}
/** Mark <b>entry_conn</b> as needing to get attached to a circuit.
*
* And <b>entry_conn</b> must be in AP_CONN_STATE_CIRCUIT_WAIT,
@ -973,9 +987,13 @@ connection_ap_mark_as_pending_circuit_(entry_connection_t *entry_conn,
if (conn->marked_for_close)
return;
if (PREDICT_UNLIKELY(NULL == pending_entry_connections))
if (PREDICT_UNLIKELY(NULL == pending_entry_connections)) {
pending_entry_connections = smartlist_new();
}
if (PREDICT_UNLIKELY(NULL == attach_pending_entry_connections_ev)) {
attach_pending_entry_connections_ev = mainloop_event_postloop_new(
attach_pending_entry_connections_cb, NULL);
}
if (PREDICT_UNLIKELY(smartlist_contains(pending_entry_connections,
entry_conn))) {
log_warn(LD_BUG, "What?? pending_entry_connections already contains %p! "
@ -999,14 +1017,7 @@ connection_ap_mark_as_pending_circuit_(entry_connection_t *entry_conn,
untried_pending_connections = 1;
smartlist_add(pending_entry_connections, entry_conn);
/* Work-around for bug 19969: we handle pending_entry_connections at
* the end of run_main_loop_once(), but in many cases that function will
* take a very long time, if ever, to finish its call to event_base_loop().
*
* So the fix is to tell it right now that it ought to finish its loop at
* its next available opportunity.
*/
tell_event_loop_to_run_external_code();
mainloop_event_activate(attach_pending_entry_connections_ev);
}
/** Mark <b>entry_conn</b> as no longer waiting for a circuit. */
@ -4165,5 +4176,6 @@ connection_edge_free_all(void)
untried_pending_connections = 0;
smartlist_free(pending_entry_connections);
pending_entry_connections = NULL;
mainloop_event_free(attach_pending_entry_connections_ev);
}

View File

@ -2867,19 +2867,6 @@ run_main_loop_once(void)
if (main_loop_should_exit)
return 0;
/* And here is where we put callbacks that happen "every time the event loop
* runs." They must be very fast, or else the whole Tor process will get
* slowed down.
*
* Note that this gets called once per libevent loop, which will make it
* happen once per group of events that fire, or once per second. */
/* If there are any pending client connections, try attaching them to
* circuits (if we can.) This will be pretty fast if nothing new is
* pending.
*/
connection_ap_attach_pending(0);
return 1;
}