From: Maxime Henrion Date: Thu, 23 May 2013 16:29:17 +0000 (+0000) Subject: Fix a double close() bug in evhttp when the underlying bufferevent uses BEV_OPT_CLOSE... X-Git-Tag: release-2.1.4-alpha~121 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=31db8a02bd74957f9ae836a38043cd9589c2d325;p=libevent Fix a double close() bug in evhttp when the underlying bufferevent uses BEV_OPT_CLOSE_ON_FREE. --- diff --git a/bufferevent-internal.h b/bufferevent-internal.h index 9ecede17..0c4df871 100644 --- a/bufferevent-internal.h +++ b/bufferevent-internal.h @@ -367,6 +367,8 @@ void bufferevent_init_generic_timeout_cbs_(struct bufferevent *bev); * that enabled EV_READ or EV_WRITE, or that disables EV_READ or EV_WRITE. */ int bufferevent_generic_adj_timeouts_(struct bufferevent *bev); +enum bufferevent_options bufferevent_get_options_(struct bufferevent *bev); + /** Internal use: We have just successfully read data into an inbuf, so * reset the read timeout (if any). */ #define BEV_RESET_GENERIC_READ_TIMEOUT(bev) \ diff --git a/bufferevent.c b/bufferevent.c index 49c1f2bc..f2f84438 100644 --- a/bufferevent.c +++ b/bufferevent.c @@ -820,6 +820,18 @@ bufferevent_getfd(struct bufferevent *bev) return (res<0) ? -1 : d.fd; } +enum bufferevent_options +bufferevent_get_options_(struct bufferevent *bev) +{ + struct bufferevent_private *bev_p = + EVUTIL_UPCAST(bev, struct bufferevent_private, bev); + + BEV_LOCK(bev); + return bev_p->options; + BEV_UNLOCK(bev); +} + + static void bufferevent_cancel_all_(struct bufferevent *bev) { diff --git a/http.c b/http.c index 22705075..2dc8206f 100644 --- a/http.c +++ b/http.c @@ -1155,7 +1155,9 @@ evhttp_connection_free(struct evhttp_connection *evcon) if (evcon->fd != -1) { shutdown(evcon->fd, EVUTIL_SHUT_WR); - evutil_closesocket(evcon->fd); + if (!(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE)) { + evutil_closesocket(evcon->fd); + } } if (evcon->bind_address != NULL)