mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-09 04:19:10 -04:00
Check more internal event_add() calls for failure
Most of these should be unable to fail, since adding a timeout generally always works. Still, it's better not to try to be "too smart for our own good here." There are some remaining event_add() calls that I didn't add checks for; I've marked those with "XXXX" comments.
This commit is contained in:
parent
7296971b10
commit
ff3f6cd42b
@ -219,7 +219,7 @@ struct bufferevent_ops {
|
||||
void (*destruct)(struct bufferevent *);
|
||||
|
||||
/** Called when the timeouts on the bufferevent have changed.*/
|
||||
void (*adj_timeouts)(struct bufferevent *);
|
||||
int (*adj_timeouts)(struct bufferevent *);
|
||||
|
||||
/** Called to flush data. */
|
||||
int (*flush)(struct bufferevent *, short, enum bufferevent_flush_mode);
|
||||
@ -304,12 +304,12 @@ int _bufferevent_add_event(struct event *ev, const struct timeval *tv);
|
||||
void _bufferevent_init_generic_timeout_cbs(struct bufferevent *bev);
|
||||
/** Internal use: Delete the ev_read and ev_write callbacks if they're pending.
|
||||
* Call this from the destructor function. */
|
||||
void _bufferevent_del_generic_timeout_cbs(struct bufferevent *bev);
|
||||
int _bufferevent_del_generic_timeout_cbs(struct bufferevent *bev);
|
||||
/** Internal use: Add or delete the generic timeout events as appropriate.
|
||||
* (If an event is enabled and a timeout is set, we add the event. Otherwise
|
||||
* we delete it.) Call this from anything that changes the timeout values,
|
||||
* that enabled EV_READ or EV_WRITE, or that disables EV_READ or EV_WRITE. */
|
||||
void _bufferevent_generic_adj_timeouts(struct bufferevent *bev);
|
||||
int _bufferevent_generic_adj_timeouts(struct bufferevent *bev);
|
||||
|
||||
/** Internal use: We have just successfully read data into an inbuf, so
|
||||
* reset the read timeout (if any). */
|
||||
|
@ -370,11 +370,12 @@ bufferevent_enable(struct bufferevent *bufev, short event)
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
bufferevent_set_timeouts(struct bufferevent *bufev,
|
||||
const struct timeval *tv_read,
|
||||
const struct timeval *tv_write)
|
||||
{
|
||||
int r = 0;
|
||||
BEV_LOCK(bufev);
|
||||
if (tv_read) {
|
||||
bufev->timeout_read = *tv_read;
|
||||
@ -388,8 +389,10 @@ bufferevent_set_timeouts(struct bufferevent *bufev,
|
||||
}
|
||||
|
||||
if (bufev->be_ops->adj_timeouts)
|
||||
bufev->be_ops->adj_timeouts(bufev);
|
||||
r = bufev->be_ops->adj_timeouts(bufev);
|
||||
BEV_UNLOCK(bufev);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@ -687,26 +690,34 @@ _bufferevent_init_generic_timeout_cbs(struct bufferevent *bev)
|
||||
bufferevent_generic_write_timeout_cb, bev);
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
_bufferevent_del_generic_timeout_cbs(struct bufferevent *bev)
|
||||
{
|
||||
event_del(&bev->ev_read);
|
||||
event_del(&bev->ev_write);
|
||||
int r1,r2;
|
||||
r1 = event_del(&bev->ev_read);
|
||||
r2 = event_del(&bev->ev_write);
|
||||
if (r2<0 || r2<0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
_bufferevent_generic_adj_timeouts(struct bufferevent *bev)
|
||||
{
|
||||
const short enabled = bev->enabled;
|
||||
int r1=0, r2=0;
|
||||
if ((enabled & EV_READ) && evutil_timerisset(&bev->timeout_read))
|
||||
event_add(&bev->ev_read, &bev->timeout_read);
|
||||
r1 = event_add(&bev->ev_read, &bev->timeout_read);
|
||||
else
|
||||
event_del(&bev->ev_read);
|
||||
r1 = event_del(&bev->ev_read);
|
||||
|
||||
if ((enabled & EV_WRITE) && evutil_timerisset(&bev->timeout_write))
|
||||
event_add(&bev->ev_write, &bev->timeout_write);
|
||||
r2 = event_add(&bev->ev_write, &bev->timeout_write);
|
||||
else
|
||||
event_del(&bev->ev_write);
|
||||
r2 = event_del(&bev->ev_write);
|
||||
if (r1 < 0 || r2 < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -242,7 +242,8 @@ be_async_enable(struct bufferevent *buf, short what)
|
||||
return -1;
|
||||
|
||||
/* NOTE: This interferes with non-blocking connect */
|
||||
_bufferevent_generic_adj_timeouts(buf);
|
||||
if (_bufferevent_generic_adj_timeouts(buf) < 0)
|
||||
return -1;
|
||||
|
||||
/* If we newly enable reading or writing, and we aren't reading or
|
||||
writing already, consider launching a new read or write. */
|
||||
|
@ -317,7 +317,7 @@ struct bufferevent_openssl {
|
||||
static int be_openssl_enable(struct bufferevent *, short);
|
||||
static int be_openssl_disable(struct bufferevent *, short);
|
||||
static void be_openssl_destruct(struct bufferevent *);
|
||||
static void be_openssl_adj_timeouts(struct bufferevent *);
|
||||
static int be_openssl_adj_timeouts(struct bufferevent *);
|
||||
static int be_openssl_flush(struct bufferevent *bufev,
|
||||
short iotype, enum bufferevent_flush_mode mode);
|
||||
static int be_openssl_ctrl(struct bufferevent *, enum bufferevent_ctrl_op, union bufferevent_ctrl_data *);
|
||||
@ -363,41 +363,45 @@ put_error(struct bufferevent_openssl *bev_ssl, unsigned long err)
|
||||
/* Have the base communications channel (either the underlying bufferevent or
|
||||
* ev_read and ev_write) start reading. Take the read-blocked-on-write flag
|
||||
* into account. */
|
||||
static void
|
||||
static int
|
||||
start_reading(struct bufferevent_openssl *bev_ssl)
|
||||
{
|
||||
if (bev_ssl->underlying) {
|
||||
short e = EV_READ;
|
||||
if (bev_ssl->read_blocked_on_write)
|
||||
e |= EV_WRITE;
|
||||
bufferevent_enable(bev_ssl->underlying, e);
|
||||
return bufferevent_enable(bev_ssl->underlying, e);
|
||||
} else {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
_bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
|
||||
if (bev_ssl->read_blocked_on_write)
|
||||
_bufferevent_add_event(&bev->ev_write,
|
||||
int r;
|
||||
r = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
|
||||
if (r == 0 && bev_ssl->read_blocked_on_write)
|
||||
r = _bufferevent_add_event(&bev->ev_write,
|
||||
&bev->timeout_write);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/* Have the base communications channel (either the underlying bufferevent or
|
||||
* ev_read and ev_write) start writing. Take the write-blocked-on-read flag
|
||||
* into account. */
|
||||
static void
|
||||
static int
|
||||
start_writing(struct bufferevent_openssl *bev_ssl)
|
||||
{
|
||||
int r;
|
||||
if (bev_ssl->underlying) {
|
||||
short e = EV_WRITE;
|
||||
if (bev_ssl->write_blocked_on_read)
|
||||
e |= EV_READ;
|
||||
bufferevent_enable(bev_ssl->underlying, e);
|
||||
r = bufferevent_enable(bev_ssl->underlying, e);
|
||||
} else {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
_bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
|
||||
if (bev_ssl->write_blocked_on_read)
|
||||
_bufferevent_add_event(&bev->ev_read,
|
||||
r = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
|
||||
if (!r && bev_ssl->write_blocked_on_read)
|
||||
r = _bufferevent_add_event(&bev->ev_read,
|
||||
&bev->timeout_read);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -426,45 +430,49 @@ stop_writing(struct bufferevent_openssl *bev_ssl)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
set_rbow(struct bufferevent_openssl *bev_ssl)
|
||||
{
|
||||
if (!bev_ssl->underlying)
|
||||
stop_reading(bev_ssl);
|
||||
bev_ssl->read_blocked_on_write = 1;
|
||||
start_writing(bev_ssl);
|
||||
return start_writing(bev_ssl);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
set_wbor(struct bufferevent_openssl *bev_ssl)
|
||||
{
|
||||
if (!bev_ssl->underlying)
|
||||
stop_writing(bev_ssl);
|
||||
bev_ssl->write_blocked_on_read = 1;
|
||||
start_reading(bev_ssl);
|
||||
return start_reading(bev_ssl);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
clear_rbow(struct bufferevent_openssl *bev_ssl)
|
||||
{
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
int r = 0;
|
||||
bev_ssl->read_blocked_on_write = 0;
|
||||
if (!(bev->enabled & EV_WRITE))
|
||||
stop_writing(bev_ssl);
|
||||
if (bev->enabled & EV_READ)
|
||||
start_reading(bev_ssl);
|
||||
r = start_reading(bev_ssl);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
static int
|
||||
clear_wbor(struct bufferevent_openssl *bev_ssl)
|
||||
{
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
int r = 0;
|
||||
bev_ssl->write_blocked_on_read = 0;
|
||||
if (!(bev->enabled & EV_READ))
|
||||
stop_reading(bev_ssl);
|
||||
if (bev->enabled & EV_WRITE)
|
||||
start_writing(bev_ssl);
|
||||
r = start_writing(bev_ssl);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -541,7 +549,8 @@ do_read(struct bufferevent_openssl *bev_ssl, int n_to_read)
|
||||
r = SSL_read(bev_ssl->ssl, space[i].iov_base, space[i].iov_len);
|
||||
if (r>0) {
|
||||
if (bev_ssl->read_blocked_on_write)
|
||||
clear_rbow(bev_ssl);
|
||||
if (clear_rbow(bev_ssl) < 0)
|
||||
return -1;
|
||||
++n_used;
|
||||
space[i].iov_len = r;
|
||||
/* Not exactly right; we probably want to do
|
||||
@ -554,13 +563,15 @@ do_read(struct bufferevent_openssl *bev_ssl, int n_to_read)
|
||||
case SSL_ERROR_WANT_READ:
|
||||
/* Can't read until underlying has more data. */
|
||||
if (bev_ssl->read_blocked_on_write)
|
||||
clear_rbow(bev_ssl);
|
||||
if (clear_rbow(bev_ssl) < 0)
|
||||
return -1;
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
/* This read operation requires a write, and the
|
||||
* underlying is full */
|
||||
if (!bev_ssl->read_blocked_on_write)
|
||||
set_rbow(bev_ssl);
|
||||
if (set_rbow(bev_ssl) < 0)
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
conn_closed(bev_ssl, err, r);
|
||||
@ -610,7 +621,8 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
|
||||
space[i].iov_len);
|
||||
if (r > 0) {
|
||||
if (bev_ssl->write_blocked_on_read)
|
||||
clear_wbor(bev_ssl);
|
||||
if (clear_wbor(bev_ssl) < 0)
|
||||
return -1;
|
||||
n_written += r;
|
||||
bev_ssl->last_write = -1;
|
||||
/* Not exactly right; we probably want to do
|
||||
@ -623,14 +635,16 @@ do_write(struct bufferevent_openssl *bev_ssl, int atmost)
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
/* Can't read until underlying has more data. */
|
||||
if (bev_ssl->write_blocked_on_read)
|
||||
clear_wbor(bev_ssl);
|
||||
if (clear_wbor(bev_ssl) < 0)
|
||||
return -1;
|
||||
bev_ssl->last_write = space[i].iov_len;
|
||||
break;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
/* This read operation requires a write, and the
|
||||
* underlying is full */
|
||||
if (!bev_ssl->write_blocked_on_read)
|
||||
set_wbor(bev_ssl);
|
||||
if (set_wbor(bev_ssl) < 0)
|
||||
return -1;
|
||||
bev_ssl->last_write = space[i].iov_len;
|
||||
break;
|
||||
default:
|
||||
@ -786,16 +800,17 @@ be_openssl_writeeventcb(evutil_socket_t fd, short what, void *ptr)
|
||||
_bufferevent_decref_and_unlock(&bev_ssl->bev.bev);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
set_open_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
|
||||
{
|
||||
if (bev_ssl->underlying) {
|
||||
bufferevent_setcb(bev_ssl->underlying,
|
||||
be_openssl_readcb, be_openssl_writecb, be_openssl_eventcb,
|
||||
bev_ssl);
|
||||
return 0;
|
||||
} else {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
int rpending=0, wpending=0;
|
||||
int rpending=0, wpending=0, r1=0, r2=0;
|
||||
if (fd < 0 && bev_ssl->fd_is_set)
|
||||
fd = event_get_fd(&bev->ev_read);
|
||||
if (bev_ssl->fd_is_set) {
|
||||
@ -809,12 +824,13 @@ set_open_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
|
||||
event_assign(&bev->ev_write, bev->ev_base, fd,
|
||||
EV_WRITE|EV_PERSIST, be_openssl_writeeventcb, bev_ssl);
|
||||
if (rpending)
|
||||
_bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
|
||||
r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
|
||||
if (wpending)
|
||||
_bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
|
||||
r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
|
||||
if (fd >= 0) {
|
||||
bev_ssl->fd_is_set = 1;
|
||||
}
|
||||
return (r1<0 || r2<0) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -837,7 +853,7 @@ do_handshake(struct bufferevent_openssl *bev_ssl)
|
||||
if (r==1) {
|
||||
/* We're done! */
|
||||
bev_ssl->state = BUFFEREVENT_SSL_OPEN;
|
||||
set_open_callbacks(bev_ssl, -1);
|
||||
set_open_callbacks(bev_ssl, -1); /* XXXX handle failure */
|
||||
/* Call do_read and do_write as needed */
|
||||
bufferevent_enable(&bev_ssl->bev.bev, bev_ssl->bev.bev.enabled);
|
||||
_bufferevent_run_eventcb(&bev_ssl->bev.bev,
|
||||
@ -850,13 +866,13 @@ do_handshake(struct bufferevent_openssl *bev_ssl)
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
if (!bev_ssl->underlying) {
|
||||
stop_reading(bev_ssl);
|
||||
start_writing(bev_ssl);
|
||||
return start_writing(bev_ssl);
|
||||
}
|
||||
return 0;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
if (!bev_ssl->underlying) {
|
||||
stop_writing(bev_ssl);
|
||||
start_reading(bev_ssl);
|
||||
return start_reading(bev_ssl);
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
@ -870,7 +886,7 @@ static void
|
||||
be_openssl_handshakecb(struct bufferevent *bev_base, void *ctx)
|
||||
{
|
||||
struct bufferevent_openssl *bev_ssl = ctx;
|
||||
do_handshake(bev_ssl);
|
||||
do_handshake(bev_ssl);/* XXX handle failure */
|
||||
}
|
||||
|
||||
static void
|
||||
@ -882,11 +898,11 @@ be_openssl_handshakeeventcb(evutil_socket_t fd, short what, void *ptr)
|
||||
if (what & EV_TIMEOUT) {
|
||||
_bufferevent_run_eventcb(&bev_ssl->bev.bev, BEV_EVENT_TIMEOUT);
|
||||
} else
|
||||
do_handshake(bev_ssl);
|
||||
do_handshake(bev_ssl);/* XXX handle failure */
|
||||
_bufferevent_decref_and_unlock(&bev_ssl->bev.bev);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
set_handshake_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
|
||||
{
|
||||
if (bev_ssl->underlying) {
|
||||
@ -894,9 +910,10 @@ set_handshake_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
|
||||
be_openssl_handshakecb, be_openssl_handshakecb,
|
||||
be_openssl_eventcb,
|
||||
bev_ssl);
|
||||
do_handshake(bev_ssl);
|
||||
return do_handshake(bev_ssl);
|
||||
} else {
|
||||
struct bufferevent *bev = &bev_ssl->bev.bev;
|
||||
int r1=0, r2=0;
|
||||
if (fd < 0 && bev_ssl->fd_is_set)
|
||||
fd = event_get_fd(&bev->ev_read);
|
||||
if (bev_ssl->fd_is_set) {
|
||||
@ -908,10 +925,11 @@ set_handshake_callbacks(struct bufferevent_openssl *bev_ssl, evutil_socket_t fd)
|
||||
event_assign(&bev->ev_write, bev->ev_base, fd,
|
||||
EV_WRITE|EV_PERSIST, be_openssl_handshakeeventcb, bev_ssl);
|
||||
if (fd >= 0) {
|
||||
_bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
|
||||
_bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
|
||||
r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
|
||||
r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
|
||||
bev_ssl->fd_is_set = 1;
|
||||
}
|
||||
return (r1<0 || r2<0) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -924,9 +942,10 @@ bufferevent_ssl_renegotiate(struct bufferevent *bev)
|
||||
if (SSL_renegotiate(bev_ssl->ssl) < 0)
|
||||
return -1;
|
||||
bev_ssl->state = BUFFEREVENT_SSL_CONNECTING;
|
||||
set_handshake_callbacks(bev_ssl, -1);
|
||||
if (set_handshake_callbacks(bev_ssl, -1) < 0)
|
||||
return -1;
|
||||
if (!bev_ssl->underlying)
|
||||
do_handshake(bev_ssl);
|
||||
return do_handshake(bev_ssl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -935,14 +954,16 @@ be_openssl_outbuf_cb(struct evbuffer *buf,
|
||||
const struct evbuffer_cb_info *cbinfo, void *arg)
|
||||
{
|
||||
struct bufferevent_openssl *bev_ssl = arg;
|
||||
int r = 0;
|
||||
/* XXX need to hold a reference here. */
|
||||
|
||||
if (cbinfo->n_added && bev_ssl->state == BUFFEREVENT_SSL_OPEN) {
|
||||
if (cbinfo->orig_size == 0)
|
||||
_bufferevent_add_event(&bev_ssl->bev.bev.ev_write,
|
||||
r = _bufferevent_add_event(&bev_ssl->bev.bev.ev_write,
|
||||
&bev_ssl->bev.bev.timeout_write);
|
||||
consider_writing(bev_ssl);
|
||||
}
|
||||
/* XXX Handle r < 0 */
|
||||
}
|
||||
|
||||
|
||||
@ -950,14 +971,15 @@ static int
|
||||
be_openssl_enable(struct bufferevent *bev, short events)
|
||||
{
|
||||
struct bufferevent_openssl *bev_ssl = upcast(bev);
|
||||
int r1 = 0, r2 = 0;
|
||||
|
||||
if (bev_ssl->state != BUFFEREVENT_SSL_OPEN)
|
||||
return 0;
|
||||
|
||||
if (events & EV_READ)
|
||||
start_reading(bev_ssl);
|
||||
r1 = start_reading(bev_ssl);
|
||||
if (events & EV_WRITE)
|
||||
start_writing(bev_ssl);
|
||||
r2 = start_writing(bev_ssl);
|
||||
|
||||
if (bev_ssl->underlying) {
|
||||
_bufferevent_generic_adj_timeouts(bev);
|
||||
@ -967,7 +989,7 @@ be_openssl_enable(struct bufferevent *bev, short events)
|
||||
if (events & EV_WRITE)
|
||||
consider_writing(bev_ssl);
|
||||
}
|
||||
return 0;
|
||||
return (r1 < 0 || r2 < 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1008,18 +1030,20 @@ be_openssl_destruct(struct bufferevent *bev)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
be_openssl_adj_timeouts(struct bufferevent *bev)
|
||||
{
|
||||
struct bufferevent_openssl *bev_ssl = upcast(bev);
|
||||
|
||||
if (bev_ssl->underlying)
|
||||
_bufferevent_generic_adj_timeouts(bev);
|
||||
return _bufferevent_generic_adj_timeouts(bev);
|
||||
else {
|
||||
int r1=0, r2=0;
|
||||
if (event_pending(&bev->ev_read, EV_READ, NULL))
|
||||
_bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
|
||||
r1 = _bufferevent_add_event(&bev->ev_read, &bev->timeout_read);
|
||||
if (event_pending(&bev->ev_write, EV_WRITE, NULL))
|
||||
_bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
|
||||
r2 = _bufferevent_add_event(&bev->ev_write, &bev->timeout_write);
|
||||
return (r1<0 || r2<0) ? -1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1050,11 +1074,10 @@ be_openssl_ctrl(struct bufferevent *bev,
|
||||
bev_ssl->fd_is_set = 1;
|
||||
}
|
||||
if (bev_ssl->state == BUFFEREVENT_SSL_OPEN)
|
||||
set_open_callbacks(bev_ssl, data->fd);
|
||||
return set_open_callbacks(bev_ssl, data->fd);
|
||||
else {
|
||||
set_handshake_callbacks(bev_ssl, data->fd);
|
||||
return set_handshake_callbacks(bev_ssl, data->fd);
|
||||
}
|
||||
return 0;
|
||||
case BEV_CTRL_GET_FD:
|
||||
if (bev_ssl->underlying)
|
||||
return -1;
|
||||
@ -1129,14 +1152,17 @@ bufferevent_openssl_new_impl(struct event_base *base,
|
||||
switch (state) {
|
||||
case BUFFEREVENT_SSL_ACCEPTING:
|
||||
SSL_set_accept_state(bev_ssl->ssl);
|
||||
set_handshake_callbacks(bev_ssl, fd);
|
||||
if (set_handshake_callbacks(bev_ssl, fd) < 0)
|
||||
goto err;
|
||||
break;
|
||||
case BUFFEREVENT_SSL_CONNECTING:
|
||||
SSL_set_connect_state(bev_ssl->ssl);
|
||||
set_handshake_callbacks(bev_ssl, fd);
|
||||
if (set_handshake_callbacks(bev_ssl, fd) < 0)
|
||||
goto err;
|
||||
break;
|
||||
case BUFFEREVENT_SSL_OPEN:
|
||||
set_open_callbacks(bev_ssl, fd);
|
||||
if (set_open_callbacks(bev_ssl, fd) < 0)
|
||||
goto err;
|
||||
break;
|
||||
default:
|
||||
goto err;
|
||||
@ -1148,8 +1174,10 @@ bufferevent_openssl_new_impl(struct event_base *base,
|
||||
bev_ssl->bev.bev.enabled = EV_READ|EV_WRITE;
|
||||
if (bev_ssl->fd_is_set) {
|
||||
/* XXX Is this quite right? */
|
||||
event_add(&bev_ssl->bev.bev.ev_read, NULL);
|
||||
event_add(&bev_ssl->bev.bev.ev_write, NULL);
|
||||
if (event_add(&bev_ssl->bev.bev.ev_read, NULL) < 0)
|
||||
goto err;
|
||||
if (event_add(&bev_ssl->bev.bev.ev_write, NULL) < 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,7 +226,8 @@ be_pair_enable(struct bufferevent *bufev, short events)
|
||||
|
||||
incref_and_lock(bufev);
|
||||
|
||||
_bufferevent_generic_adj_timeouts(bufev);
|
||||
if (_bufferevent_generic_adj_timeouts(bufev) < 0)
|
||||
return -1;
|
||||
|
||||
/* We're starting to read! Does the other side have anything to write?*/
|
||||
if ((events & EV_READ) && partner &&
|
||||
@ -245,8 +246,7 @@ be_pair_enable(struct bufferevent *bufev, short events)
|
||||
static int
|
||||
be_pair_disable(struct bufferevent *bev, short events)
|
||||
{
|
||||
_bufferevent_generic_adj_timeouts(bev);
|
||||
return 0;
|
||||
return _bufferevent_generic_adj_timeouts(bev);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -256,6 +256,8 @@ _bufferevent_get_write_max(struct bufferevent_private *bev)
|
||||
int
|
||||
_bufferevent_decrement_read_buckets(struct bufferevent_private *bev, int bytes)
|
||||
{
|
||||
/* XXXXX Make sure all users of this function check its return value */
|
||||
int r = 0;
|
||||
/* need to hold lock on bev */
|
||||
if (!bev->rate_limiting)
|
||||
return 0;
|
||||
@ -264,8 +266,9 @@ _bufferevent_decrement_read_buckets(struct bufferevent_private *bev, int bytes)
|
||||
bev->rate_limiting->limit.read_limit -= bytes;
|
||||
if (bev->rate_limiting->limit.read_limit <= 0) {
|
||||
bufferevent_suspend_read(&bev->bev, BEV_SUSPEND_BW);
|
||||
event_add(&bev->rate_limiting->refill_bucket_event,
|
||||
&bev->rate_limiting->cfg->tick_timeout);
|
||||
if (event_add(&bev->rate_limiting->refill_bucket_event,
|
||||
&bev->rate_limiting->cfg->tick_timeout) < 0)
|
||||
r = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,12 +281,14 @@ _bufferevent_decrement_read_buckets(struct bufferevent_private *bev, int bytes)
|
||||
UNLOCK_GROUP(bev->rate_limiting->group);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
_bufferevent_decrement_write_buckets(struct bufferevent_private *bev, int bytes)
|
||||
{
|
||||
/* XXXXX Make sure all users of this function check its return value */
|
||||
int r = 0;
|
||||
/* need to hold lock */
|
||||
if (!bev->rate_limiting)
|
||||
return 0;
|
||||
@ -292,8 +297,9 @@ _bufferevent_decrement_write_buckets(struct bufferevent_private *bev, int bytes)
|
||||
bev->rate_limiting->limit.write_limit -= bytes;
|
||||
if (bev->rate_limiting->limit.write_limit <= 0) {
|
||||
bufferevent_suspend_write(&bev->bev, BEV_SUSPEND_BW);
|
||||
event_add(&bev->rate_limiting->refill_bucket_event,
|
||||
&bev->rate_limiting->cfg->tick_timeout);
|
||||
if (event_add(&bev->rate_limiting->refill_bucket_event,
|
||||
&bev->rate_limiting->cfg->tick_timeout) < 0)
|
||||
r = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,7 +312,7 @@ _bufferevent_decrement_write_buckets(struct bufferevent_private *bev, int bytes)
|
||||
UNLOCK_GROUP(bev->rate_limiting->group);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Stop reading on every bufferevent in <b>g</b> */
|
||||
@ -395,6 +401,7 @@ _bev_refill_callback(evutil_socket_t fd, short what, void *arg)
|
||||
XXXX if we need to be quiet for more ticks, we should
|
||||
maybe figure out what timeout we really want.
|
||||
*/
|
||||
/* XXXX Handle event_add failure somehow */
|
||||
event_add(&bev->rate_limiting->refill_bucket_event,
|
||||
&bev->rate_limiting->cfg->tick_timeout);
|
||||
}
|
||||
@ -579,6 +586,7 @@ bufferevent_rate_limit_group_new(struct event_base *base,
|
||||
g->min_share = 64;
|
||||
event_assign(&g->master_refill_event, base, -1, EV_PERSIST,
|
||||
_bev_group_refill_callback, g);
|
||||
/*XXXX handle event_add failure */
|
||||
event_add(&g->master_refill_event, &cfg->tick_timeout);
|
||||
|
||||
EVTHREAD_ALLOC_LOCK(g->lock, EVTHREAD_LOCKTYPE_RECURSIVE);
|
||||
|
@ -78,7 +78,7 @@
|
||||
static int be_socket_enable(struct bufferevent *, short);
|
||||
static int be_socket_disable(struct bufferevent *, short);
|
||||
static void be_socket_destruct(struct bufferevent *);
|
||||
static void be_socket_adj_timeouts(struct bufferevent *);
|
||||
static int be_socket_adj_timeouts(struct bufferevent *);
|
||||
static int be_socket_flush(struct bufferevent *, short, enum bufferevent_flush_mode);
|
||||
static int be_socket_ctrl(struct bufferevent *, enum bufferevent_ctrl_op, union bufferevent_ctrl_data *);
|
||||
|
||||
@ -111,6 +111,7 @@ bufferevent_socket_outbuf_cb(struct evbuffer *buf,
|
||||
/* Somebody added data to the buffer, and we would like to
|
||||
* write, and we were not writing. So, start writing. */
|
||||
be_socket_add(&bufev->ev_write, &bufev->timeout_write);
|
||||
/* XXXX handle failure from be_socket_add */
|
||||
}
|
||||
}
|
||||
|
||||
@ -539,13 +540,17 @@ be_socket_destruct(struct bufferevent *bufev)
|
||||
EVUTIL_CLOSESOCKET(fd);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
be_socket_adj_timeouts(struct bufferevent *bufev)
|
||||
{
|
||||
int r = 0;
|
||||
if (event_pending(&bufev->ev_read, EV_READ, NULL))
|
||||
be_socket_add(&bufev->ev_read, &bufev->timeout_read);
|
||||
if (be_socket_add(&bufev->ev_read, &bufev->timeout_read) < 0)
|
||||
r = -1;
|
||||
if (event_pending(&bufev->ev_write, EV_WRITE, NULL))
|
||||
be_socket_add(&bufev->ev_write, &bufev->timeout_write);
|
||||
if (be_socket_add(&bufev->ev_write, &bufev->timeout_write) < 0)
|
||||
r = -1;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
|
6
evdns.c
6
evdns.c
@ -4113,11 +4113,11 @@ evdns_getaddrinfo_timeout_cb(evutil_socket_t fd, short what, void *ptr)
|
||||
free_getaddrinfo_request(data);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
evdns_getaddrinfo_set_timeout(struct evdns_base *evdns_base,
|
||||
struct evdns_getaddrinfo_request *data)
|
||||
{
|
||||
event_add(&data->timeout, &evdns_base->global_getaddrinfo_allow_skew);
|
||||
return event_add(&data->timeout, &evdns_base->global_getaddrinfo_allow_skew);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4178,6 +4178,7 @@ evdns_getaddrinfo_gotresolve(int result, char type, int count,
|
||||
if (other_req->r) {
|
||||
/* The other request is still working; maybe it will
|
||||
* succeed. */
|
||||
/* XXXX handle failure from set_timeout */
|
||||
evdns_getaddrinfo_set_timeout(data->evdns_base, data);
|
||||
data->pending_error = err;
|
||||
return;
|
||||
@ -4243,6 +4244,7 @@ evdns_getaddrinfo_gotresolve(int result, char type, int count,
|
||||
|
||||
if (other_req->r) {
|
||||
/* The other request is still in progress; wait for it */
|
||||
/* XXXX handle failure from set_timeout */
|
||||
evdns_getaddrinfo_set_timeout(data->evdns_base, data);
|
||||
data->pending_result = res;
|
||||
return;
|
||||
|
7
http.c
7
http.c
@ -303,7 +303,7 @@ evhttp_response_needs_body(struct evhttp_request *req)
|
||||
req->type != EVHTTP_REQ_HEAD);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
evhttp_add_event(struct event *ev, int timeout, int default_timeout)
|
||||
{
|
||||
if (timeout != 0) {
|
||||
@ -311,9 +311,9 @@ evhttp_add_event(struct event *ev, int timeout, int default_timeout)
|
||||
|
||||
evutil_timerclear(&tv);
|
||||
tv.tv_sec = timeout != -1 ? timeout : default_timeout;
|
||||
event_add(ev, &tv);
|
||||
return event_add(ev, &tv);
|
||||
} else {
|
||||
event_add(ev, NULL);
|
||||
return event_add(ev, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1067,6 +1067,7 @@ evhttp_connection_cb_cleanup(struct evhttp_connection *evcon)
|
||||
{
|
||||
if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) {
|
||||
evtimer_assign(&evcon->retry_ev, evcon->base, evhttp_connection_retry, evcon);
|
||||
/* XXXX handle failure from evhttp_add_event */
|
||||
evhttp_add_event(&evcon->retry_ev,
|
||||
MIN(3600, 2 << evcon->retry_cnt),
|
||||
HTTP_CONNECT_TIMEOUT);
|
||||
|
@ -371,7 +371,7 @@ short bufferevent_get_enabled(struct bufferevent *bufev);
|
||||
@param timeout_read the read timeout, or NULL
|
||||
@param timeout_write the write timeout, or NULL
|
||||
*/
|
||||
void bufferevent_set_timeouts(struct bufferevent *bufev,
|
||||
int bufferevent_set_timeouts(struct bufferevent *bufev,
|
||||
const struct timeval *timeout_read, const struct timeval *timeout_write);
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user