]> granicus.if.org Git - libevent/commitdiff
Check more internal event_add() calls for failure
authorNick Mathewson <nickm@torproject.org>
Fri, 22 Jan 2010 21:14:49 +0000 (16:14 -0500)
committerNick Mathewson <nickm@torproject.org>
Fri, 22 Jan 2010 21:14:49 +0000 (16:14 -0500)
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.

bufferevent-internal.h
bufferevent.c
bufferevent_async.c
bufferevent_openssl.c
bufferevent_pair.c
bufferevent_ratelim.c
bufferevent_sock.c
evdns.c
http.c
include/event2/bufferevent.h

index 9594784a2a32d3196ab61410060ba245710650b0..eca52e77340413a00dbe241c544bd48de1c04942 100644 (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). */
index 6e6c41870e17231181b59c562894c9b201ee8c38..77f18240ca3e2b5e7e06dd02f71e32fb31e419f2 100644 (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
index 3d21d4c13a30634aba808beabb8a6be5db115bc6..085a2db82efa5a270ab4891fbbc4d4fd954634b1 100644 (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. */
index 26be4ff1e03fd6a58c5c9cc4055bcfa37e3c4c73..3a239a44cbc730c60d2e7e9d3cf007fb0562740d 100644 (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;
                }
        }
 
index 34880462610880d7c11dcf05af52f8ffe5258ec5..fc00a7c2773c94b569f2e3904bf13f4102c0f154 100644 (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
index 968168adf8ef4d0de34c6e9023d935b942f93ba2..bbbadcad713e31c2f87096d6226be492bb0691ff 100644 (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);
index 30bc44bc0b79acaf9cb9c69cd359a815f04ccd76..36893a75d9039a59031d8617b755dc0572837922 100644 (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
diff --git a/evdns.c b/evdns.c
index 0d3906d4b27316ff16a2e357b05d2eff4dc22de6..fdf7026ebc110234ee5e197650125069da6eab52 100644 (file)
--- a/evdns.c
+++ b/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;
diff --git a/http.c b/http.c
index ec47d13c1d8dd1b0a907a34e6bd8adccad950a7b..0c742c1cac1233ae74507dba1d6376df68cd0c1a 100644 (file)
--- a/http.c
+++ b/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);
index 48d56bd6a4940b6c82fa38745159fad9624bd1ef..2b8bb6f600b197ca57a9342424ebcaac7d5eae26 100644 (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);
 
 /**