From 972b456bf60e9a2f550ec45a14921c06e252c793 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 5 May 2020 00:21:18 +0300 Subject: [PATCH] Fix EV_CLOSED detection/reporting (epoll only) - EV_CLOSED is EPOLLRDHUP in epoll - EPOLLRDHUP reported w/o EPOLLHUP if the socket closed with shutdown(SHUT_WR) - EPOLLRDHUP reported w/ EPOLLHUP if the socket closed with close() so in this case epoll backend will detect this event as error (EV_READ|EV_WRITE), since the epoll_ctl() will return EPOLLRDHUP with EPOLLHUP set, but this is not correct, let's fix this. Fixes: #984 --- epoll.c | 4 +++- test/regress.c | 9 ++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/epoll.c b/epoll.c index 299e3d355c..4b1e3963d1 100644 --- a/epoll.c +++ b/epoll.c @@ -487,7 +487,9 @@ epoll_dispatch(struct event_base *base, struct timeval *tv) continue; #endif - if (what & (EPOLLHUP|EPOLLERR)) { + if (what & EPOLLERR) { + ev = EV_READ | EV_WRITE; + } else if ((what & EPOLLHUP) && !(what & EPOLLRDHUP)) { ev = EV_READ | EV_WRITE; } else { if (what & EPOLLIN) diff --git a/test/regress.c b/test/regress.c index 53c0718319..fe2a8fd1e1 100644 --- a/test/regress.c +++ b/test/regress.c @@ -512,13 +512,8 @@ test_simpleclose(void *ptr) tt_assert(!event_base_loopexit(base, &tv)); } - /* via close() */ - if (pair[1] == -1) { - tt_int_op(event_base_loop(base, EVLOOP_NONBLOCK), ==, 0); - } else { - tt_int_op(event_base_loop(base, EVLOOP_NONBLOCK), ==, !persist); - tt_int_op(got_event, ==, (events & ~EV_PERSIST)); - } + tt_int_op(event_base_loop(base, EVLOOP_NONBLOCK), ==, !persist); + tt_int_op(got_event, ==, (events & ~EV_PERSIST)); end: if (ev)