packages/net/haproxy/patches/0039-MEDIUM-poll-do-not-use-FD_-macros-anymore.patch
heil 89cca70763 package: haproxy
- add backported patches for 1.4.22



git-svn-id: svn://svn.openwrt.org/openwrt/packages@36152 3c298f89-4303-0410-b956-a3cf2f4a3e73
2013-04-02 13:52:02 +00:00

194 lines
5.5 KiB
Diff

From d9185dbab66e8ea3bafd1d43660ae44311da7a81 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Sun, 31 Mar 2013 14:06:57 +0200
Subject: [PATCH 39/42] MEDIUM: poll: do not use FD_* macros anymore
Some recent glibc updates have added controls on FD_SET/FD_CLR/FD_ISSET
that crash the program if it tries to use a file descriptor larger than
FD_SETSIZE.
Do not rely on FD_* macros anymore and replace them with bit fields.
(cherry picked from commit 80da05a4cfb881663dc1f38a94d613f37e54552a)
---
src/ev_poll.c | 87 +++++++++++++++++++++++++++++------------------------------
1 file changed, 43 insertions(+), 44 deletions(-)
diff --git a/src/ev_poll.c b/src/ev_poll.c
index f5d011e..02e89ad 100644
--- a/src/ev_poll.c
+++ b/src/ev_poll.c
@@ -27,12 +27,25 @@
#include <proto/task.h>
-static fd_set *fd_evts[2];
+static unsigned int *fd_evts[2];
/* private data */
static struct pollfd *poll_events = NULL;
+static inline unsigned int hap_fd_isset(int fd, unsigned int *evts)
+{
+ return evts[fd / (8*sizeof(*evts))] & (1U << (fd & (8*sizeof(*evts) - 1)));
+}
+
+static inline void hap_fd_set(int fd, unsigned int *evts)
+{
+ evts[fd / (8*sizeof(*evts))] |= 1U << (fd & (8*sizeof(*evts) - 1));
+}
+static inline void hap_fd_clr(int fd, unsigned int *evts)
+{
+ evts[fd / (8*sizeof(*evts))] &= ~(1U << (fd & (8*sizeof(*evts) - 1)));
+}
/*
* Benchmarks performed on a Pentium-M notebook show that using functions
* instead of the usual macros improve the FD_* performance by about 80%,
@@ -40,43 +53,43 @@ static struct pollfd *poll_events = NULL;
*/
REGPRM2 static int __fd_is_set(const int fd, int dir)
{
- return FD_ISSET(fd, fd_evts[dir]);
+ return hap_fd_isset(fd, fd_evts[dir]);
}
REGPRM2 static int __fd_set(const int fd, int dir)
{
- FD_SET(fd, fd_evts[dir]);
+ hap_fd_set(fd, fd_evts[dir]);
return 0;
}
REGPRM2 static int __fd_clr(const int fd, int dir)
{
- FD_CLR(fd, fd_evts[dir]);
+ hap_fd_clr(fd, fd_evts[dir]);
return 0;
}
REGPRM2 static int __fd_cond_s(const int fd, int dir)
{
int ret;
- ret = !FD_ISSET(fd, fd_evts[dir]);
+ ret = !hap_fd_isset(fd, fd_evts[dir]);
if (ret)
- FD_SET(fd, fd_evts[dir]);
+ hap_fd_set(fd, fd_evts[dir]);
return ret;
}
REGPRM2 static int __fd_cond_c(const int fd, int dir)
{
int ret;
- ret = FD_ISSET(fd, fd_evts[dir]);
+ ret = hap_fd_isset(fd, fd_evts[dir]);
if (ret)
- FD_CLR(fd, fd_evts[dir]);
+ hap_fd_clr(fd, fd_evts[dir]);
return ret;
}
REGPRM1 static void __fd_rem(const int fd)
{
- FD_CLR(fd, fd_evts[DIR_RD]);
- FD_CLR(fd, fd_evts[DIR_WR]);
+ hap_fd_clr(fd, fd_evts[DIR_RD]);
+ hap_fd_clr(fd, fd_evts[DIR_WR]);
}
/*
@@ -93,33 +106,20 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
unsigned rn, wn; /* read new, write new */
nbfd = 0;
- for (fds = 0; (fds * BITS_PER_INT) < maxfd; fds++) {
-
- rn = ((int*)fd_evts[DIR_RD])[fds];
- wn = ((int*)fd_evts[DIR_WR])[fds];
+ for (fds = 0; (fds * 8*sizeof(**fd_evts)) < maxfd; fds++) {
+ rn = fd_evts[DIR_RD][fds];
+ wn = fd_evts[DIR_WR][fds];
- if ((rn|wn)) {
- for (count = 0, fd = fds * BITS_PER_INT; count < BITS_PER_INT && fd < maxfd; count++, fd++) {
-#define FDSETS_ARE_INT_ALIGNED
-#ifdef FDSETS_ARE_INT_ALIGNED
-
-#define WE_REALLY_KNOW_THAT_FDSETS_ARE_INTS
-#ifdef WE_REALLY_KNOW_THAT_FDSETS_ARE_INTS
- sr = (rn >> count) & 1;
- sw = (wn >> count) & 1;
-#else
- sr = FD_ISSET(fd&(BITS_PER_INT-1), (typeof(fd_set*))&rn);
- sw = FD_ISSET(fd&(BITS_PER_INT-1), (typeof(fd_set*))&wn);
-#endif
-#else
- sr = FD_ISSET(fd, fd_evts[DIR_RD]);
- sw = FD_ISSET(fd, fd_evts[DIR_WR]);
-#endif
- if ((sr|sw)) {
- poll_events[nbfd].fd = fd;
- poll_events[nbfd].events = (sr ? POLLIN : 0) | (sw ? POLLOUT : 0);
- nbfd++;
- }
+ if (!(rn|wn))
+ continue;
+
+ for (count = 0, fd = fds * 8*sizeof(**fd_evts); count < 8*sizeof(**fd_evts) && fd < maxfd; count++, fd++) {
+ sr = (rn >> count) & 1;
+ sw = (wn >> count) & 1;
+ if ((sr|sw)) {
+ poll_events[nbfd].fd = fd;
+ poll_events[nbfd].events = (sr ? POLLIN : 0) | (sw ? POLLOUT : 0);
+ nbfd++;
}
}
}
@@ -149,14 +149,14 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
/* ok, we found one active fd */
status--;
- if (FD_ISSET(fd, fd_evts[DIR_RD])) {
+ if (hap_fd_isset(fd, fd_evts[DIR_RD])) {
if (fdtab[fd].state == FD_STCLOSE)
continue;
if (poll_events[count].revents & ( POLLIN | POLLERR | POLLHUP ))
fdtab[fd].cb[DIR_RD].f(fd);
}
- if (FD_ISSET(fd, fd_evts[DIR_WR])) {
+ if (hap_fd_isset(fd, fd_evts[DIR_WR])) {
if (fdtab[fd].state == FD_STCLOSE)
continue;
if (poll_events[count].revents & ( POLLOUT | POLLERR | POLLHUP ))
@@ -174,21 +174,20 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
REGPRM1 static int _do_init(struct poller *p)
{
__label__ fail_swevt, fail_srevt, fail_pe;
- int fd_set_bytes;
+ int fd_evts_bytes;
p->private = NULL;
- fd_set_bytes = sizeof(fd_set) * (global.maxsock + FD_SETSIZE - 1) / FD_SETSIZE;
+ fd_evts_bytes = (global.maxsock + sizeof(**fd_evts) - 1) / sizeof(**fd_evts) * sizeof(**fd_evts);
- poll_events = (struct pollfd*)
- calloc(1, sizeof(struct pollfd) * global.maxsock);
+ poll_events = calloc(1, sizeof(struct pollfd) * global.maxsock);
if (poll_events == NULL)
goto fail_pe;
- if ((fd_evts[DIR_RD] = (fd_set *)calloc(1, fd_set_bytes)) == NULL)
+ if ((fd_evts[DIR_RD] = calloc(1, fd_evts_bytes)) == NULL)
goto fail_srevt;
- if ((fd_evts[DIR_WR] = (fd_set *)calloc(1, fd_set_bytes)) == NULL)
+ if ((fd_evts[DIR_WR] = calloc(1, fd_evts_bytes)) == NULL)
goto fail_swevt;
return 1;
--
1.8.1.5