mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-05 03:29:35 +00:00
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.
This commit is contained in:
parent
b67fdc4cd8
commit
80da05a4cf
@ -27,16 +27,31 @@
|
||||
#include <proto/task.h>
|
||||
|
||||
|
||||
static fd_set *fd_evts[2];
|
||||
static unsigned int *fd_evts[2];
|
||||
|
||||
/* private data */
|
||||
static struct pollfd *poll_events = NULL;
|
||||
|
||||
|
||||
REGPRM1 static void __fd_clo(const int fd)
|
||||
static inline unsigned int hap_fd_isset(int fd, unsigned int *evts)
|
||||
{
|
||||
FD_CLR(fd, fd_evts[DIR_RD]);
|
||||
FD_CLR(fd, fd_evts[DIR_WR]);
|
||||
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)));
|
||||
}
|
||||
|
||||
REGPRM1 static void __fd_clo(int fd)
|
||||
{
|
||||
hap_fd_clr(fd, fd_evts[DIR_RD]);
|
||||
hap_fd_clr(fd, fd_evts[DIR_WR]);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -62,14 +77,14 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
||||
if ((eo ^ en) & FD_EV_POLLED_RW) {
|
||||
/* poll status changed, update the lists */
|
||||
if ((eo & ~en) & FD_EV_POLLED_R)
|
||||
FD_CLR(fd, fd_evts[DIR_RD]);
|
||||
hap_fd_clr(fd, fd_evts[DIR_RD]);
|
||||
else if ((en & ~eo) & FD_EV_POLLED_R)
|
||||
FD_SET(fd, fd_evts[DIR_RD]);
|
||||
hap_fd_set(fd, fd_evts[DIR_RD]);
|
||||
|
||||
if ((eo & ~en) & FD_EV_POLLED_W)
|
||||
FD_CLR(fd, fd_evts[DIR_WR]);
|
||||
hap_fd_clr(fd, fd_evts[DIR_WR]);
|
||||
else if ((en & ~eo) & FD_EV_POLLED_W)
|
||||
FD_SET(fd, fd_evts[DIR_WR]);
|
||||
hap_fd_set(fd, fd_evts[DIR_WR]);
|
||||
}
|
||||
|
||||
fdtab[fd].spec_e = (en << 4) + en; /* save new events */
|
||||
@ -92,33 +107,20 @@ REGPRM2 static void _do_poll(struct poller *p, int exp)
|
||||
fd_nbupdt = 0;
|
||||
|
||||
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
|
||||
if (!(rn|wn))
|
||||
continue;
|
||||
|
||||
#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++;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -202,21 +204,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;
|
||||
|
Loading…
Reference in New Issue
Block a user