mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-09 04:19:10 -04:00
Support EV_CLOSED on linux for poll(2)
Refs: #984 (cherry picked from commit 4c13afaeec2d35df2580dfbc49391d0524101248)
This commit is contained in:
parent
1df324d4c4
commit
2530e7c630
23
poll.c
23
poll.c
@ -53,6 +53,17 @@
|
|||||||
#include "evthread-internal.h"
|
#include "evthread-internal.h"
|
||||||
#include "time-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 {
|
struct pollidx {
|
||||||
int idxplus1;
|
int idxplus1;
|
||||||
};
|
};
|
||||||
@ -80,7 +91,7 @@ const struct eventop pollops = {
|
|||||||
poll_dispatch,
|
poll_dispatch,
|
||||||
poll_dealloc,
|
poll_dealloc,
|
||||||
0, /* doesn't need_reinit */
|
0, /* doesn't need_reinit */
|
||||||
EV_FEATURE_FDS,
|
EV_FEATURE_FDS|EARLY_CLOSE_IF_HAVE_RDHUP,
|
||||||
sizeof(struct pollidx),
|
sizeof(struct pollidx),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -204,6 +215,8 @@ poll_dispatch(struct event_base *base, struct timeval *tv)
|
|||||||
res |= EV_READ;
|
res |= EV_READ;
|
||||||
if (what & POLLOUT)
|
if (what & POLLOUT)
|
||||||
res |= EV_WRITE;
|
res |= EV_WRITE;
|
||||||
|
if (what & POLLRDHUP)
|
||||||
|
res |= EV_CLOSED;
|
||||||
if (res == 0)
|
if (res == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -222,7 +235,7 @@ poll_add(struct event_base *base, int fd, short old, short events, void *idx_)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
EVUTIL_ASSERT((events & EV_SIGNAL) == 0);
|
EVUTIL_ASSERT((events & EV_SIGNAL) == 0);
|
||||||
if (!(events & (EV_READ|EV_WRITE)))
|
if (!(events & (EV_READ|EV_WRITE|EV_CLOSED)))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
poll_check_ok(pop);
|
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;
|
pfd->events |= POLLOUT;
|
||||||
if (events & EV_READ)
|
if (events & EV_READ)
|
||||||
pfd->events |= POLLIN;
|
pfd->events |= POLLIN;
|
||||||
|
if (events & EV_CLOSED)
|
||||||
|
pfd->events |= POLLRDHUP;
|
||||||
poll_check_ok(pop);
|
poll_check_ok(pop);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
@ -283,7 +298,7 @@ poll_del(struct event_base *base, int fd, short old, short events, void *idx_)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
EVUTIL_ASSERT((events & EV_SIGNAL) == 0);
|
EVUTIL_ASSERT((events & EV_SIGNAL) == 0);
|
||||||
if (!(events & (EV_READ|EV_WRITE)))
|
if (!(events & (EV_READ|EV_WRITE|EV_CLOSED)))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
poll_check_ok(pop);
|
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;
|
pfd->events &= ~POLLIN;
|
||||||
if (events & EV_WRITE)
|
if (events & EV_WRITE)
|
||||||
pfd->events &= ~POLLOUT;
|
pfd->events &= ~POLLOUT;
|
||||||
|
if (events & EV_CLOSED)
|
||||||
|
pfd->events &= ~POLLRDHUP;
|
||||||
poll_check_ok(pop);
|
poll_check_ok(pop);
|
||||||
if (pfd->events)
|
if (pfd->events)
|
||||||
/* Another event cares about that fd. */
|
/* Another event cares about that fd. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user