
- add backported patches for 1.4.22 git-svn-id: svn://svn.openwrt.org/openwrt/packages@36152 3c298f89-4303-0410-b956-a3cf2f4a3e73
194 lines
5.5 KiB
Diff
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
|
|
|