From ab3bc69f47925299a919493f306b9d6fbb805b00 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 20 Nov 2015 01:37:46 +0300 Subject: [PATCH] http: avoid epoll_ctl() on already closed fd (triggers by http/chunk_out) Before: $ strace -eepoll_ctl,close regress --verbose --no-fork +http/chunk_out close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 http/chunk_out: epoll_ctl(5, EPOLL_CTL_ADD, 8, {EPOLLIN, {u32=8, u64=8}}) = 0 close(10) = 0 close(9) = 0 epoll_ctl(5, EPOLL_CTL_ADD, 9, {EPOLLIN, {u32=9, u64=9}}) = 0 epoll_ctl(5, EPOLL_CTL_ADD, 10, {EPOLLOUT, {u32=10, u64=10}}) = 0 epoll_ctl(5, EPOLL_CTL_ADD, 11, {EPOLLIN, {u32=11, u64=11}}) = 0 epoll_ctl(5, EPOLL_CTL_DEL, 10, 7ffffb10b870) = 0 epoll_ctl(5, EPOLL_CTL_ADD, 10, {EPOLLIN, {u32=10, u64=10}}) = 0 close(12) = 0 epoll_ctl(5, EPOLL_CTL_MOD, 11, {EPOLLIN|EPOLLOUT, {u32=11, u64=11}}) = 0 epoll_ctl(5, EPOLL_CTL_MOD, 11, {EPOLLIN, {u32=11, u64=11}}) = 0 close(11) = 0 epoll_ctl(5, EPOLL_CTL_DEL, 11, 7ffffb10b770) = -1 EBADF (Bad file descriptor) ... And trace for latest: close(11) = 0 > regress(evutil_closesocket+0x15) [0xadac4] > regress(evhttp_connection_free+0x19d) [0xbada2] > regress(evhttp_send_done+0x14d) [0xbde43] > regress(evhttp_write_cb+0x4a) [0xba1a1] > regress(bufferevent_run_writecb_+0xa2) [0x97bba] > regress(bufferevent_trigger_nolock_+0xb1) [0x9e330] > regress(bufferevent_writecb+0x2a3) [0x9e91a] > regress(event_persist_closure+0x2bb) [0xa2e09] > regress(event_process_active_single_queue+0x2a8) [0xa30b4] > regress(event_process_active+0x13f) [0xa3696] > regress(event_base_loop+0x2ab) [0xa3d97] > regress(event_base_dispatch+0x1d) [0xa371e] > regress(http_chunk_out_test_impl+0x132) [0x74940] epoll_ctl(5, EPOLL_CTL_DEL, 11, 7fff09439fe0) = -1 EBADF (Bad file descriptor) > regress(epoll_ctl+0x36) [0xb49a3] > regress(epoll_apply_one_change+0x14e) [0xb4cd4] > regress(epoll_nochangelist_del+0x87) [0xb51e4] > regress(evmap_io_del_+0x247) [0xaab04] > regress(event_del_nolock_+0x2f7) [0xa6aa8] > regress(event_callback_cancel_nolock_+0x6e) [0xa747e] > regress(event_callback_finalize_many_+0xeb) [0xa4dd6] > regress(bufferevent_decref_and_unlock_+0x21d) [0x98da7] > regress(bufferevent_writecb+0x312) [0x9e989] > regress(event_persist_closure+0x2bb) [0xa2e09] > regress(event_process_active_single_queue+0x2a8) [0xa30b4] > regress(event_process_active+0x13f) [0xa3696] > regress(event_base_loop+0x2ab) [0xa3d97] > regress(event_base_dispatch+0x1d) [0xa371e] > regress(http_chunk_out_test_impl+0x132) [0x74940] ... --- http.c | 1 + 1 file changed, 1 insertion(+) diff --git a/http.c b/http.c index b879132a..7d7ff07c 100644 --- a/http.c +++ b/http.c @@ -1192,6 +1192,7 @@ evhttp_connection_free(struct evhttp_connection *evcon) &evcon->read_more_deferred_cb); if (evcon->fd != -1) { + bufferevent_disable(evcon->bufev, EV_READ|EV_WRITE); shutdown(evcon->fd, EVUTIL_SHUT_WR); if (!(bufferevent_get_options_(evcon->bufev) & BEV_OPT_CLOSE_ON_FREE)) { evutil_closesocket(evcon->fd);