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]
 ...
This commit is contained in:
Azat Khuzhin 2015-11-20 01:37:46 +03:00
parent 040000d7a7
commit ab3bc69f47

1
http.c
View File

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