summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThuan Tran <thuan.tran@edgeware.tv>2023-05-15 10:18:38 +0700
committerAzat Khuzhin <azat@libevent.org>2023-05-16 21:11:54 +0200
commitef51444f439b922c8fb00c7ef3f8482b6400b6ea (patch)
tree38d371df82033c12c779dee83258b2fef53ce6b3
parent4ab3242da1b5ae5d99ff2086df935057880ca9ff (diff)
downloadlibevent-ef51444f439b922c8fb00c7ef3f8482b6400b6ea.tar.gz
More SSL_read() to fill big buffer
Once SSL_read() only get max 16K bytes (one TLS record). In case of big buffer, should more SSL_read() to fill the buffer. Using sample https-client to measure max income MBit/s via nload tool. Note: set bufferevent_set_max_single_read() by 32K and add the chunk callback to read out each piece of data. The client sample do https request a data 900KB (the server don't use Transfer-Encoding: chunked) - With origin/master: max income is 2.26 MBit/s The chunk callback never get a piece of data > 16K. - With this PR: max income is 2.44 MBit/s The chunk callback can get some piece of data 32K or more.
-rw-r--r--bufferevent_ssl.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/bufferevent_ssl.c b/bufferevent_ssl.c
index 58945e62..c74fd283 100644
--- a/bufferevent_ssl.c
+++ b/bufferevent_ssl.c
@@ -253,9 +253,10 @@ do_read(struct bufferevent_ssl *bev_ssl, int n_to_read) {
/* Requires lock */
struct bufferevent *bev = &bev_ssl->bev.bev;
struct evbuffer *input = bev->input;
- int r, n, i, n_used = 0, atmost;
+ int r, n, i = 0, atmost;
struct evbuffer_iovec space[2];
int result = 0;
+ size_t len = 0;
if (bev_ssl->bev.read_suspended)
return 0;
@@ -268,23 +269,30 @@ do_read(struct bufferevent_ssl *bev_ssl, int n_to_read) {
if (n < 0)
return OP_ERR;
- for (i=0; i<n; ++i) {
+ for (i = 0; i < n;) {
if (bev_ssl->bev.read_suspended)
break;
bev_ssl->ssl_ops->clear_error();
- r = bev_ssl->ssl_ops->read(bev_ssl->ssl, space[i].iov_base, space[i].iov_len);
- if (r>0) {
+ r = bev_ssl->ssl_ops->read(
+ bev_ssl->ssl, (unsigned char *)space[i].iov_base + len, space[i].iov_len - len);
+ if (r > 0) {
result |= OP_MADE_PROGRESS;
if (bev_ssl->read_blocked_on_write)
if (clear_rbow(bev_ssl) < 0)
return OP_ERR | result;
- ++n_used;
- space[i].iov_len = r;
bev_ssl->ssl_ops->decrement_buckets(bev_ssl);
+ len += r;
+ if (space[i].iov_len - len > 0) {
+ continue;
+ } else {
+ space[i].iov_len = len;
+ len = 0;
+ ++i;
+ }
} else {
int err = bev_ssl->ssl_ops->get_error(bev_ssl->ssl, r);
bev_ssl->ssl_ops->print_err(err);
- if (bev_ssl->ssl_ops->err_is_ok(err) && result & OP_MADE_PROGRESS) {
+ if (result & OP_MADE_PROGRESS) {
/* Process existing data */
break;
} else if (bev_ssl->ssl_ops->err_is_want_read(err)) {
@@ -292,7 +300,7 @@ do_read(struct bufferevent_ssl *bev_ssl, int n_to_read) {
if (bev_ssl->read_blocked_on_write)
if (clear_rbow(bev_ssl) < 0)
return OP_ERR | result;
- } else if(bev_ssl->ssl_ops->err_is_want_write(err)) {
+ } else if (bev_ssl->ssl_ops->err_is_want_write(err)) {
/* This read operation requires a write, and the
* underlying is full */
if (!bev_ssl->read_blocked_on_write)
@@ -306,8 +314,13 @@ do_read(struct bufferevent_ssl *bev_ssl, int n_to_read) {
}
}
- if (n_used) {
- evbuffer_commit_space(input, space, n_used);
+ if (len > 0) {
+ space[i].iov_len = len;
+ ++i;
+ }
+
+ if (i) {
+ evbuffer_commit_space(input, space, i);
if (bev_ssl->underlying)
BEV_RESET_GENERIC_READ_TIMEOUT(bev);
}