]> granicus.if.org Git - libevent/commitdiff
Fix a double close() bug in evhttp when the underlying bufferevent uses BEV_OPT_CLOSE...
authorMaxime Henrion <mhenrion@appnexus.com>
Thu, 23 May 2013 16:29:17 +0000 (16:29 +0000)
committerNick Mathewson <nickm@torproject.org>
Fri, 24 May 2013 15:04:11 +0000 (11:04 -0400)
bufferevent-internal.h
bufferevent.c
http.c

index 9ecede179a8de7832e7d3a77bda3e6c95538b392..0c4df871fa7059589c8f78791808d188ab04cece 100644 (file)
@@ -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)                            \
index 49c1f2bc39acf3adaccb91928eee10cc9cb1648b..f2f844389c7c0d89b6bc6d59660fd11f9c3253b3 100644 (file)
@@ -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 227050759415bea9dfbce1221ec8f9434bbdba16..2dc8206f70a27d05d503661ff63a4e5c407ccef7 100644 (file)
--- 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)