mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
Merge remote-tracking branch 'origin/patches-2.0'
This commit is contained in:
commit
e3d010c8f6
@ -559,15 +559,20 @@ decrement_buckets(struct bufferevent_openssl *bev_ssl)
|
||||
bev_ssl->counts.n_read = num_r;
|
||||
}
|
||||
|
||||
/* returns -1 on internal error, 0 on stall, 1 on progress */
|
||||
static int
|
||||
do_read(struct bufferevent_openssl *bev_ssl, int n_to_read)
|
||||
{
|
||||
#define OP_MADE_PROGRESS 1
|
||||
#define OP_BLOCKED 2
|
||||
#define OP_ERR 4
|
||||
|
||||
/* Return a bitmask of OP_MADE_PROGRESS (if we read anything); OP_BLOCKED (if
|
||||
we're now blocked); and OP_ERR (if an error occurred). */
|
||||
static int
|
||||
do_read(struct bufferevent_openssl *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, blocked = 0, atmost;
|
||||
int r, n, i, n_used = 0, atmost;
|
||||
struct evbuffer_iovec space[2];
|
||||
int result = 0;
|
||||
|
||||
atmost = bufferevent_get_read_max_(&bev_ssl->bev);
|
||||
if (n_to_read > atmost)
|
||||
@ -575,16 +580,17 @@ do_read(struct bufferevent_openssl *bev_ssl, int n_to_read)
|
||||
|
||||
n = evbuffer_reserve_space(input, n_to_read, space, 2);
|
||||
if (n < 0)
|
||||
return -1;
|
||||
return OP_ERR;
|
||||
|
||||
for (i=0; i<n; ++i) {
|
||||
if (bev_ssl->bev.read_suspended)
|
||||
break;
|
||||
r = SSL_read(bev_ssl->ssl, space[i].iov_base, space[i].iov_len);
|
||||
if (r>0) {
|
||||
result |= OP_MADE_PROGRESS;
|
||||
if (bev_ssl->read_blocked_on_write)
|
||||
if (clear_rbow(bev_ssl) < 0)
|
||||
return -1;
|
||||
return OP_ERR | result;
|
||||
++n_used;
|
||||
space[i].iov_len = r;
|
||||
decrement_buckets(bev_ssl);
|
||||
@ -596,20 +602,20 @@ do_read(struct bufferevent_openssl *bev_ssl, int n_to_read)
|
||||
/* Can't read until underlying has more data. */
|
||||
if (bev_ssl->read_blocked_on_write)
|
||||
if (clear_rbow(bev_ssl) < 0)
|
||||
return -1;
|
||||
return OP_ERR | result;
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
/* This read operation requires a write, and the
|
||||
* underlying is full */
|
||||
if (!bev_ssl->read_blocked_on_write)
|
||||
if (set_rbow(bev_ssl) < 0)
|
||||
return -1;
|
||||
return OP_ERR | result;
|
||||
break;
|
||||
default:
|
||||
conn_closed(bev_ssl, BEV_EVENT_READING, err, r);
|
||||
break;
|
||||
}
|
||||
blocked = 1;
|
||||
result |= OP_BLOCKED;
|
||||
break; /* out of the loop */
|
||||
}
|
||||
}
|
||||
@ -620,16 +626,19 @@ do_read(struct bufferevent_openssl *bev_ssl, int n_to_read)
|
||||
BEV_RESET_GENERIC_READ_TIMEOUT(bev);
|
||||
}
|
||||
|
||||
return blocked ? 0 : 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return a bitmask of OP_MADE_PROGRESS (if we wrote anything); OP_BLOCKED (if
|
||||
we're now blocked); and OP_ERR (if an error occurred). */
|
||||
static int
|
||||
do_write(struct bufferevent_openssl *bev_ssl, int atmost)
|
||||
{
|
||||
int i, r, n, n_written = 0, blocked=0;
|
||||
int i, r, n, n_written = 0;
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
struct evbuffer *output = bev->output;
|
||||
struct evbuffer_iovec space[8];
|
||||
int result = 0;
|
||||
|
||||
if (bev_ssl->last_write > 0)
|
||||
atmost = bev_ssl->last_write;
|
||||
@ -638,7 +647,7 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
|
||||
|
||||
n = evbuffer_peek(output, atmost, NULL, space, 8);
|
||||
if (n < 0)
|
||||
return -1;
|
||||
return OP_ERR | result;
|
||||
|
||||
if (n > 8)
|
||||
n = 8;
|
||||
@ -655,9 +664,10 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
|
||||
r = SSL_write(bev_ssl->ssl, space[i].iov_base,
|
||||
space[i].iov_len);
|
||||
if (r > 0) {
|
||||
result |= OP_MADE_PROGRESS;
|
||||
if (bev_ssl->write_blocked_on_read)
|
||||
if (clear_wbor(bev_ssl) < 0)
|
||||
return -1;
|
||||
return OP_ERR | result;
|
||||
n_written += r;
|
||||
bev_ssl->last_write = -1;
|
||||
decrement_buckets(bev_ssl);
|
||||
@ -669,7 +679,7 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
|
||||
/* Can't read until underlying has more data. */
|
||||
if (bev_ssl->write_blocked_on_read)
|
||||
if (clear_wbor(bev_ssl) < 0)
|
||||
return -1;
|
||||
return OP_ERR | result;
|
||||
bev_ssl->last_write = space[i].iov_len;
|
||||
break;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
@ -677,7 +687,7 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
|
||||
* underlying is full */
|
||||
if (!bev_ssl->write_blocked_on_read)
|
||||
if (set_wbor(bev_ssl) < 0)
|
||||
return -1;
|
||||
return OP_ERR | result;
|
||||
bev_ssl->last_write = space[i].iov_len;
|
||||
break;
|
||||
default:
|
||||
@ -685,7 +695,7 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
|
||||
bev_ssl->last_write = -1;
|
||||
break;
|
||||
}
|
||||
blocked = 1;
|
||||
result |= OP_BLOCKED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -697,7 +707,7 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
|
||||
if (evbuffer_get_length(output) <= bev->wm_write.low)
|
||||
bufferevent_run_writecb_(bev);
|
||||
}
|
||||
return blocked ? 0 : 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
#define WRITE_FRAME 15000
|
||||
@ -757,11 +767,11 @@ consider_reading(struct bufferevent_openssl *bev_ssl)
|
||||
{
|
||||
int r;
|
||||
int n_to_read;
|
||||
int read_data = 0;
|
||||
int all_result_flags = 0;
|
||||
|
||||
while (bev_ssl->write_blocked_on_read) {
|
||||
r = do_write(bev_ssl, WRITE_FRAME);
|
||||
if (r <= 0)
|
||||
if (r & (OP_BLOCKED|OP_ERR))
|
||||
break;
|
||||
}
|
||||
if (bev_ssl->write_blocked_on_read)
|
||||
@ -770,10 +780,11 @@ consider_reading(struct bufferevent_openssl *bev_ssl)
|
||||
n_to_read = bytes_to_read(bev_ssl);
|
||||
|
||||
while (n_to_read) {
|
||||
if (do_read(bev_ssl, n_to_read) <= 0)
|
||||
break;
|
||||
r = do_read(bev_ssl, n_to_read);
|
||||
all_result_flags |= r;
|
||||
|
||||
read_data = 1;
|
||||
if (r & (OP_BLOCKED|OP_ERR))
|
||||
break;
|
||||
|
||||
/* Read all pending data. This won't hit the network
|
||||
* again, and will (most importantly) put us in a state
|
||||
@ -803,7 +814,7 @@ consider_reading(struct bufferevent_openssl *bev_ssl)
|
||||
n_to_read = bytes_to_read(bev_ssl);
|
||||
}
|
||||
|
||||
if (read_data == 1) {
|
||||
if (all_result_flags & OP_MADE_PROGRESS) {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
struct evbuffer *input = bev->input;
|
||||
|
||||
@ -831,9 +842,7 @@ consider_writing(struct bufferevent_openssl *bev_ssl)
|
||||
|
||||
while (bev_ssl->read_blocked_on_write) {
|
||||
r = do_read(bev_ssl, 1024); /* XXXX 1024 is a hack */
|
||||
if (r <= 0)
|
||||
break;
|
||||
else {
|
||||
if (r & OP_MADE_PROGRESS) {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
struct evbuffer *input = bev->input;
|
||||
|
||||
@ -841,6 +850,8 @@ consider_writing(struct bufferevent_openssl *bev_ssl)
|
||||
bufferevent_run_readcb_(bev);
|
||||
}
|
||||
}
|
||||
if (r & (OP_ERR|OP_BLOCKED))
|
||||
break;
|
||||
}
|
||||
if (bev_ssl->read_blocked_on_write)
|
||||
return;
|
||||
@ -858,7 +869,7 @@ consider_writing(struct bufferevent_openssl *bev_ssl)
|
||||
else
|
||||
n_to_write = WRITE_FRAME;
|
||||
r = do_write(bev_ssl, n_to_write);
|
||||
if (r <= 0)
|
||||
if (r & (OP_BLOCKED|OP_ERR))
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user