From 5a767693b5c068b1142ddb540b9aeb26748fcdfc Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 13 Mar 2017 11:38:28 +0100 Subject: [PATCH] MINOR: fd: add a new flag HAP_POLL_F_RDHUP to struct poller We'll need to differenciate between pollers which can report hangup at the same time as read (POLL_RDHUP) from the other ones, because only these ones may benefit from the fd_done_recv() optimization. Epoll has had support for EPOLLRDHUP since Linux 2.6.17 and has always been used this way in haproxy, so now we only set the flag once we've observed it once in a response. It means that some initial requests may try to perform a second recv() call, but after the first closed connection it will be enough to know that the second call is not needed anymore. Later we may extend these flags to designate event-triggered pollers. --- include/types/fd.h | 5 +++++ src/ev_epoll.c | 5 ++++- src/ev_kqueue.c | 1 + src/ev_poll.c | 1 + src/ev_select.c | 1 + 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/types/fd.h b/include/types/fd.h index 7f6309354..2bd7c07f2 100644 --- a/include/types/fd.h +++ b/include/types/fd.h @@ -120,7 +120,11 @@ struct fdinfo { * the term() function. * - clo() should be used to do indicate the poller that fd will be closed. * - poll() calls the poller, expiring at + * - flags indicate what the poller supports (HAP_POLL_F_*) */ + +#define HAP_POLL_F_RDHUP 0x00000001 /* the poller notifies of HUP with reads */ + struct poller { void *private; /* any private data for the poller */ void REGPRM1 (*clo)(const int fd); /* mark as closed */ @@ -130,6 +134,7 @@ struct poller { int REGPRM1 (*test)(struct poller *p); /* pre-init check of the poller */ int REGPRM1 (*fork)(struct poller *p); /* post-fork re-opening */ const char *name; /* poller name */ + unsigned int flags; /* HAP_POLL_F_* */ int pref; /* try pollers with higher preference first */ }; diff --git a/src/ev_epoll.c b/src/ev_epoll.c index ccb7c3377..eb2bceb03 100644 --- a/src/ev_epoll.c +++ b/src/ev_epoll.c @@ -154,8 +154,10 @@ REGPRM2 static void _do_poll(struct poller *p, int exp) } /* always remap RDHUP to HUP as they're used similarly */ - if (e & EPOLLRDHUP) + if (e & EPOLLRDHUP) { + cur_poller.flags |= HAP_POLL_F_RDHUP; n |= FD_POLL_HUP; + } fdtab[fd].ev |= n; if (n & (FD_POLL_IN | FD_POLL_HUP | FD_POLL_ERR)) @@ -263,6 +265,7 @@ static void _do_register(void) p->name = "epoll"; p->pref = 300; + p->flags = 0; p->private = NULL; p->clo = __fd_clo; diff --git a/src/ev_kqueue.c b/src/ev_kqueue.c index 081e78aa7..de7da655b 100644 --- a/src/ev_kqueue.c +++ b/src/ev_kqueue.c @@ -234,6 +234,7 @@ static void _do_register(void) p->name = "kqueue"; p->pref = 300; + p->flags = 0; p->private = NULL; p->clo = NULL; diff --git a/src/ev_poll.c b/src/ev_poll.c index 80d88eb91..9a6faa9bf 100644 --- a/src/ev_poll.c +++ b/src/ev_poll.c @@ -235,6 +235,7 @@ static void _do_register(void) p->name = "poll"; p->pref = 200; + p->flags = 0; p->private = NULL; p->clo = __fd_clo; diff --git a/src/ev_select.c b/src/ev_select.c index 35d3c77db..1b40ea102 100644 --- a/src/ev_select.c +++ b/src/ev_select.c @@ -235,6 +235,7 @@ static void _do_register(void) p->name = "select"; p->pref = 150; + p->flags = 0; p->private = NULL; p->clo = __fd_clo; -- 2.47.3