From aa6717ce213e79735c72afc5ec9cc1f9c0297e09 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 May 2016 21:36:18 -0700 Subject: [PATCH] xfree86: Switch from select(2) to poll(2) xf86WaitForInput and the xf86 SIGIO handling code. Signed-off-by: Keith Packard Reviewed-by: Adam Jackson --- hw/xfree86/common/xf86Events.c | 1 - hw/xfree86/os-support/shared/posix_tty.c | 33 ++++-------- hw/xfree86/os-support/shared/sigio.c | 64 ++++++++++++++++-------- 3 files changed, 53 insertions(+), 45 deletions(-) diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index 5db0dfb8e..7b9c33aeb 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -54,7 +54,6 @@ #endif #include -#include #include #include #include "misc.h" diff --git a/hw/xfree86/os-support/shared/posix_tty.c b/hw/xfree86/os-support/shared/posix_tty.c index 6e2af001a..d5a70ba3e 100644 --- a/hw/xfree86/os-support/shared/posix_tty.c +++ b/hw/xfree86/os-support/shared/posix_tty.c @@ -57,6 +57,7 @@ #endif #include +#include #include "xf86.h" #include "xf86Priv.h" #include "xf86_OSlib.h" @@ -387,26 +388,19 @@ xf86CloseSerial(int fd) int xf86WaitForInput(int fd, int timeout) { - fd_set readfds; - struct timeval to; int r; + struct pollfd poll_fd; - FD_ZERO(&readfds); + poll_fd.fd = fd; + poll_fd.events = POLLIN; if (fd >= 0) { - FD_SET(fd, &readfds); - } - - to.tv_sec = timeout / 1000000; - to.tv_usec = timeout % 1000000; - - if (fd >= 0) { - SYSCALL(r = select(FD_SETSIZE, &readfds, NULL, NULL, &to)); + SYSCALL(r = poll(&poll_fd, 1, timeout)); } else { - SYSCALL(r = select(FD_SETSIZE, NULL, NULL, NULL, &to)); + SYSCALL(r = poll(&poll_fd, 0, timeout)); } - xf86ErrorFVerb(9, "select returned %d\n", r); + xf86ErrorFVerb(9, "poll returned %d\n", r); return r; } @@ -423,8 +417,7 @@ xf86SerialSendBreak(int fd, int duration) int xf86FlushInput(int fd) { - fd_set fds; - struct timeval timeout; + struct pollfd poll_fd; /* this needs to be big enough to flush an evdev event. */ char c[256]; @@ -432,15 +425,11 @@ xf86FlushInput(int fd) if (tcflush(fd, TCIFLUSH) == 0) return 0; - timeout.tv_sec = 0; - timeout.tv_usec = 0; - FD_ZERO(&fds); - FD_SET(fd, &fds); - while (select(FD_SETSIZE, &fds, NULL, NULL, &timeout) > 0) { + poll_fd.fd = fd; + poll_fd.events = POLLIN; + while (poll(&poll_fd, 1, 0) > 0) { if (read(fd, &c, sizeof(c)) < 1) return 0; - FD_ZERO(&fds); - FD_SET(fd, &fds); } return 0; } diff --git a/hw/xfree86/os-support/shared/sigio.c b/hw/xfree86/os-support/shared/sigio.c index 37ef38f34..949d1b477 100644 --- a/hw/xfree86/os-support/shared/sigio.c +++ b/hw/xfree86/os-support/shared/sigio.c @@ -57,6 +57,7 @@ #endif #include +#include #include "xf86.h" #include "xf86Priv.h" #include "xf86_OSlib.h" @@ -83,8 +84,36 @@ typedef struct _xf86SigIOFunc { static Xf86SigIOFunc xf86SigIOFuncs[MAX_FUNCS]; static int xf86SigIOMax; -static int xf86SigIOMaxFd; -static fd_set xf86SigIOMask; +static struct pollfd *xf86SigIOFds; +static int xf86SigIONum; + +static Bool +xf86SigIOAdd(int fd) +{ + struct pollfd *n; + + n = realloc(xf86SigIOFds, (xf86SigIONum + 1) * sizeof (struct pollfd)); + if (!n) + return FALSE; + + n[xf86SigIONum].fd = fd; + n[xf86SigIONum].events = POLLIN; + xf86SigIONum++; + xf86SigIOFds = n; + return TRUE; +} + +static void +xf86SigIORemove(int fd) +{ + int i; + for (i = 0; i < xf86SigIONum; i++) + if (xf86SigIOFds[i].fd == fd) { + memmove(&xf86SigIOFds[i], &xf86SigIOFds[i+1], (xf86SigIONum - i - 1) * sizeof (struct pollfd)); + xf86SigIONum--; + break; + } +} /* * SIGIO gives no way of discovering which fd signalled, select @@ -93,24 +122,22 @@ static fd_set xf86SigIOMask; static void xf86SIGIO(int sig) { - int i; - fd_set ready; - struct timeval to; + int i, f; int save_errno = errno; /* do not clobber the global errno */ int r; inSignalContext = TRUE; - ready = xf86SigIOMask; - to.tv_sec = 0; - to.tv_usec = 0; - SYSCALL(r = select(xf86SigIOMaxFd, &ready, 0, 0, &to)); - for (i = 0; r > 0 && i < xf86SigIOMax; i++) - if (xf86SigIOFuncs[i].f && FD_ISSET(xf86SigIOFuncs[i].fd, &ready)) { - (*xf86SigIOFuncs[i].f) (xf86SigIOFuncs[i].fd, - xf86SigIOFuncs[i].closure); + SYSCALL(r = poll(xf86SigIOFds, xf86SigIONum, 0)); + for (f = 0; r > 0 && f < xf86SigIONum; f++) { + if (xf86SigIOFds[f].revents & POLLIN) { + for (i = 0; i < xf86SigIOMax; i++) + if (xf86SigIOFuncs[i].f && xf86SigIOFuncs[i].fd == xf86SigIOFds[f].fd) + (*xf86SigIOFuncs[i].f) (xf86SigIOFuncs[i].fd, + xf86SigIOFuncs[i].closure); r--; } + } if (r > 0) { xf86Msg(X_ERROR, "SIGIO %d descriptors not handled\n", r); } @@ -206,9 +233,7 @@ xf86InstallSIGIOHandler(int fd, void (*f) (int, void *), void *closure) xf86SigIOFuncs[i].f = f; if (i >= xf86SigIOMax) xf86SigIOMax = i + 1; - if (fd >= xf86SigIOMaxFd) - xf86SigIOMaxFd = fd + 1; - FD_SET(fd, &xf86SigIOMask); + xf86SigIOAdd(fd); release_sigio(); return 1; } @@ -229,14 +254,12 @@ xf86RemoveSIGIOHandler(int fd) struct sigaction osa; int i; int max; - int maxfd; int ret; if (!xf86Info.useSIGIO) return 0; max = 0; - maxfd = -1; ret = 0; for (i = 0; i < MAX_FUNCS; i++) { if (xf86SigIOFuncs[i].f) { @@ -244,13 +267,11 @@ xf86RemoveSIGIOHandler(int fd) xf86SigIOFuncs[i].f = 0; xf86SigIOFuncs[i].fd = 0; xf86SigIOFuncs[i].closure = 0; - FD_CLR(fd, &xf86SigIOMask); + xf86SigIORemove(fd); ret = 1; } else { max = i + 1; - if (xf86SigIOFuncs[i].fd >= maxfd) - maxfd = xf86SigIOFuncs[i].fd + 1; } } } @@ -267,7 +288,6 @@ xf86RemoveSIGIOHandler(int fd) } #endif xf86SigIOMax = max; - xf86SigIOMaxFd = maxfd; if (!max) { sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO);