Fix a 100%-CPU bug where an SSL connection would sometimes never stop trying to write

If an SSL connection becamse disabled or suspended before became open,
it could (under the right circumstances) wind up without ever getting
its write callback disabled.

The most correct fix is probably more subtle, and involves checking
all caseswhen a write callback is enabled or disabled.  This fix is
more blunt, and explicitly checks whether the callback should have
been disabled at the end of the callback to prevent infinite looping.

Diagnosed with help from Sebastian Hahn
This commit is contained in:
Nick Mathewson 2010-10-20 13:41:02 -04:00
parent f13e449b53
commit 1213d3dd8b

View File

@ -732,6 +732,14 @@ consider_reading(struct bufferevent_openssl *bev_ssl)
if (r <= 0)
break;
}
if (!bev_ssl->underlying) {
/* Should be redundant, but let's avoid busy-looping */
if (bev_ssl->bev.read_suspended ||
!(bev_ssl->bev.bev.enabled & EV_READ)) {
event_del(&bev_ssl->bev.bev.ev_read);
}
}
}
static void
@ -767,8 +775,15 @@ consider_writing(struct bufferevent_openssl *bev_ssl)
break;
}
if (!bev_ssl->underlying && !evbuffer_get_length(output))
event_del(&bev_ssl->bev.bev.ev_write);
if (!bev_ssl->underlying) {
if (evbuffer_get_length(output) == 0) {
event_del(&bev_ssl->bev.bev.ev_write);
} else if (bev_ssl->bev.write_suspended ||
!(bev_ssl->bev.bev.enabled & EV_WRITE)) {
/* Should be redundant, but let's avoid busy-looping */
event_del(&bev_ssl->bev.bev.ev_write);
}
}
}
static void