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:
Nick Mathewson 2010-01-22 16:14:49 -05:00
parent 7296971b10
commit ff3f6cd42b
10 changed files with 145 additions and 89 deletions

View File

@ -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). */

View File

@ -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

View File

@ -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. */

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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
View File

@ -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);

View File

@ -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);
/**