diff options
Diffstat (limited to 'poll.c')
-rw-r--r-- | poll.c | 25 |
1 files changed, 21 insertions, 4 deletions
@@ -53,6 +53,17 @@ #include "evthread-internal.h" #include "time-internal.h" +/* Since Linux 2.6.17, poll is able to report about peer half-closed connection + using special POLLRDHUP flag on a read event. +*/ +#if !defined(POLLRDHUP) +#define POLLRDHUP 0 +#define EARLY_CLOSE_IF_HAVE_RDHUP 0 +#else +#define EARLY_CLOSE_IF_HAVE_RDHUP EV_FEATURE_EARLY_CLOSE +#endif + + struct pollidx { int idxplus1; }; @@ -79,8 +90,8 @@ const struct eventop pollops = { poll_del, poll_dispatch, poll_dealloc, - 0, /* doesn't need_reinit */ - EV_FEATURE_FDS, + 1, /* need_reinit */ + EV_FEATURE_FDS|EARLY_CLOSE_IF_HAVE_RDHUP, sizeof(struct pollidx), }; @@ -204,6 +215,8 @@ poll_dispatch(struct event_base *base, struct timeval *tv) res |= EV_READ; if (what & POLLOUT) res |= EV_WRITE; + if (what & POLLRDHUP) + res |= EV_CLOSED; if (res == 0) continue; @@ -222,7 +235,7 @@ poll_add(struct event_base *base, int fd, short old, short events, void *idx_) int i; EVUTIL_ASSERT((events & EV_SIGNAL) == 0); - if (!(events & (EV_READ|EV_WRITE))) + if (!(events & (EV_READ|EV_WRITE|EV_CLOSED))) return (0); poll_check_ok(pop); @@ -265,6 +278,8 @@ poll_add(struct event_base *base, int fd, short old, short events, void *idx_) pfd->events |= POLLOUT; if (events & EV_READ) pfd->events |= POLLIN; + if (events & EV_CLOSED) + pfd->events |= POLLRDHUP; poll_check_ok(pop); return (0); @@ -283,7 +298,7 @@ poll_del(struct event_base *base, int fd, short old, short events, void *idx_) int i; EVUTIL_ASSERT((events & EV_SIGNAL) == 0); - if (!(events & (EV_READ|EV_WRITE))) + if (!(events & (EV_READ|EV_WRITE|EV_CLOSED))) return (0); poll_check_ok(pop); @@ -297,6 +312,8 @@ poll_del(struct event_base *base, int fd, short old, short events, void *idx_) pfd->events &= ~POLLIN; if (events & EV_WRITE) pfd->events &= ~POLLOUT; + if (events & EV_CLOSED) + pfd->events &= ~POLLRDHUP; poll_check_ok(pop); if (pfd->events) /* Another event cares about that fd. */ |