diff options
author | Nick Mathewson <nickm@torproject.org> | 2019-10-09 16:26:31 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2019-10-09 16:26:31 -0400 |
commit | 99809834a7aac5239b4b1bd7c74215d53856663b (patch) | |
tree | 9a38685298e361141946bf41393d611bf3d3289b /src/core | |
parent | 1f60337da4bc1b813489482d9001285e9b104d3d (diff) | |
parent | 841cff6e4fe1cdd370cd51019e69c6c564e8059c (diff) | |
download | tor-99809834a7aac5239b4b1bd7c74215d53856663b.tar.gz tor-99809834a7aac5239b4b1bd7c74215d53856663b.zip |
Merge branch 'bug30344_squashed_035'
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/mainloop/connection.c | 18 | ||||
-rw-r--r-- | src/core/mainloop/mainloop.c | 10 |
2 files changed, 22 insertions, 6 deletions
diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c index 348d90a63e..6094f33e4d 100644 --- a/src/core/mainloop/connection.c +++ b/src/core/mainloop/connection.c @@ -900,13 +900,19 @@ connection_mark_for_close_(connection_t *conn, int line, const char *file) } /** Mark <b>conn</b> to be closed next time we loop through - * conn_close_if_marked() in main.c; the _internal version bypasses the - * CONN_TYPE_OR checks; this should be called when you either are sure that - * if this is an or_connection_t the controlling channel has been notified - * (e.g. with connection_or_notify_error()), or you actually are the + * conn_close_if_marked() in main.c. + * + * This _internal version bypasses the CONN_TYPE_OR checks; this should be + * called when you either are sure that if this is an or_connection_t the + * controlling channel has been notified (e.g. with + * connection_or_notify_error()), or you actually are the * connection_or_close_for_error() or connection_or_close_normally() function. - * For all other cases, use connection_mark_and_flush() instead, which - * checks for or_connection_t properly, instead. See below. + * For all other cases, use connection_mark_and_flush() which checks for + * or_connection_t properly, instead. See below. + * + * We want to keep this function simple and quick, since it can be called from + * quite deep in the call chain, and hence it should avoid having side-effects + * that interfere with its callers view of the connection. */ MOCK_IMPL(void, connection_mark_for_close_internal_, (connection_t *conn, diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c index c051b11566..2f8be9961d 100644 --- a/src/core/mainloop/mainloop.c +++ b/src/core/mainloop/mainloop.c @@ -874,6 +874,16 @@ conn_read_callback(evutil_socket_t fd, short event, void *_conn) /* assert_connection_ok(conn, time(NULL)); */ + /* Handle marked for close connections early */ + if (conn->marked_for_close && connection_is_reading(conn)) { + /* Libevent says we can read, but we are marked for close so we will never + * try to read again. We will try to close the connection below inside of + * close_closeable_connections(), but let's make sure not to cause Libevent + * to spin on conn_read_callback() while we wait for the socket to let us + * flush to it.*/ + connection_stop_reading(conn); + } + if (connection_handle_read(conn) < 0) { if (!conn->marked_for_close) { #ifndef _WIN32 |