Avoid busy-looping on WANTREAD within connection_handle_write

Fix for bug 5650.  Also, if we get a WANTREAD while reading while
writing, make sure we're reading.
This commit is contained in:
Nick Mathewson 2013-04-10 19:30:41 -04:00
parent 9630fb917f
commit 39ac1db60e
3 changed files with 24 additions and 1 deletions

5
changes/bug5650 Normal file
View File

@ -0,0 +1,5 @@
o Major bugfixes:
- Avoid a bug where our response to TLS renegotation under certain
network conditions could lead to a busy-loop, with 100% CPU
consumption. Fixes bug 5650; bugfix on 0.2.0.16-alpha.

View File

@ -2825,7 +2825,20 @@ connection_read_to_buf(connection_t *conn, ssize_t *max_to_read,
case TOR_TLS_WANTWRITE:
connection_start_writing(conn);
return 0;
case TOR_TLS_WANTREAD: /* we're already reading */
case TOR_TLS_WANTREAD:
if (conn->in_connection_handle_write) {
/* We've been invoked from connection_handle_write, because we're
* waiting for a TLS renegotiation, the renegotiation started, and
* SSL_read returned WANTWRITE. But now SSL_read is saying WANTREAD
* again. Stop waiting for write events now, or else we'll
* busy-loop until data arrives for us to read. */
connection_stop_writing(conn);
if (!connection_is_reading(conn))
connection_start_reading(conn);
}
/* we're already reading, one hopes */
result = 0;
break;
case TOR_TLS_DONE: /* no data read, so nothing to process */
result = 0;
break; /* so we call bucket_decrement below */
@ -3337,7 +3350,9 @@ connection_handle_write(connection_t *conn, int force)
{
int res;
tor_gettimeofday_cache_clear();
conn->in_connection_handle_write = 1;
res = connection_handle_write_impl(conn, force);
conn->in_connection_handle_write = 0;
return res;
}

View File

@ -998,6 +998,9 @@ typedef struct connection_t {
/** Set to 1 when we're inside connection_flushed_some to keep us from
* calling connection_handle_write() recursively. */
unsigned int in_flushed_some:1;
/** True if connection_handle_write is currently running on this connection.
*/
unsigned int in_connection_handle_write:1;
/* For linked connections:
*/