Avoid potential SSL read spinlocks

OpenSSL bufferevents with deferred callbacks enabled under high load will
spinlock in the function consider_reading(). This loop continues until all
data has been read.

Because of this condition; openssl bufferevents will never return back into
event_base_loop() until SSL_read has determined data is no longer ready.

As of yet I have not found a reason why this while loop exists, so this patch
just swaps out while for if.

If needed I can write same code which would trigger this effect; optionally
libevhtp has a test.c program which can be run with the following flags:

./test -s <keyfile.pem>

curl -vvvv -k -d@<HUGE_ASS_FILE> https://127.0.0.1:8081/

The return data will include the number of times the readcb got data and the
length of that read.

Without this patch, you are likely to see a small amount of "bytes read....",
otherwise the "bytes read..." return data should show much more reasonable
numbers.
This commit is contained in:
Mark Ellzey 2011-11-14 10:24:07 -05:00 committed by Nick Mathewson
parent a3f320e83d
commit fc52dbac87

View File

@ -722,15 +722,13 @@ consider_reading(struct bufferevent_openssl *bev_ssl)
}
if (bev_ssl->write_blocked_on_read)
return;
while ((bev_ssl->bev.bev.enabled & EV_READ) &&
if ((bev_ssl->bev.bev.enabled & EV_READ) &&
(! bev_ssl->bev.read_suspended) &&
(! wm->high || evbuffer_get_length(input) < wm->high)) {
int n_to_read =
wm->high ? wm->high - evbuffer_get_length(input)
: READ_DEFAULT;
r = do_read(bev_ssl, n_to_read);
if (r <= 0)
break;
}
if (!bev_ssl->underlying) {