xfree86: Switch from select(2) to poll(2)

xf86WaitForInput and the xf86 SIGIO handling code.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
Keith Packard 2016-05-24 21:36:18 -07:00 committed by Adam Jackson
parent 81135991a5
commit aa6717ce21
3 changed files with 53 additions and 45 deletions

View File

@ -54,7 +54,6 @@
#endif #endif
#include <X11/X.h> #include <X11/X.h>
#include <X11/Xpoll.h>
#include <X11/Xproto.h> #include <X11/Xproto.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include "misc.h" #include "misc.h"

View File

@ -57,6 +57,7 @@
#endif #endif
#include <X11/X.h> #include <X11/X.h>
#include <poll.h>
#include "xf86.h" #include "xf86.h"
#include "xf86Priv.h" #include "xf86Priv.h"
#include "xf86_OSlib.h" #include "xf86_OSlib.h"
@ -387,26 +388,19 @@ xf86CloseSerial(int fd)
int int
xf86WaitForInput(int fd, int timeout) xf86WaitForInput(int fd, int timeout)
{ {
fd_set readfds;
struct timeval to;
int r; int r;
struct pollfd poll_fd;
FD_ZERO(&readfds); poll_fd.fd = fd;
poll_fd.events = POLLIN;
if (fd >= 0) { if (fd >= 0) {
FD_SET(fd, &readfds); SYSCALL(r = poll(&poll_fd, 1, timeout));
}
to.tv_sec = timeout / 1000000;
to.tv_usec = timeout % 1000000;
if (fd >= 0) {
SYSCALL(r = select(FD_SETSIZE, &readfds, NULL, NULL, &to));
} }
else { 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; return r;
} }
@ -423,8 +417,7 @@ xf86SerialSendBreak(int fd, int duration)
int int
xf86FlushInput(int fd) xf86FlushInput(int fd)
{ {
fd_set fds; struct pollfd poll_fd;
struct timeval timeout;
/* this needs to be big enough to flush an evdev event. */ /* this needs to be big enough to flush an evdev event. */
char c[256]; char c[256];
@ -432,15 +425,11 @@ xf86FlushInput(int fd)
if (tcflush(fd, TCIFLUSH) == 0) if (tcflush(fd, TCIFLUSH) == 0)
return 0; return 0;
timeout.tv_sec = 0; poll_fd.fd = fd;
timeout.tv_usec = 0; poll_fd.events = POLLIN;
FD_ZERO(&fds); while (poll(&poll_fd, 1, 0) > 0) {
FD_SET(fd, &fds);
while (select(FD_SETSIZE, &fds, NULL, NULL, &timeout) > 0) {
if (read(fd, &c, sizeof(c)) < 1) if (read(fd, &c, sizeof(c)) < 1)
return 0; return 0;
FD_ZERO(&fds);
FD_SET(fd, &fds);
} }
return 0; return 0;
} }

View File

@ -57,6 +57,7 @@
#endif #endif
#include <X11/X.h> #include <X11/X.h>
#include <poll.h>
#include "xf86.h" #include "xf86.h"
#include "xf86Priv.h" #include "xf86Priv.h"
#include "xf86_OSlib.h" #include "xf86_OSlib.h"
@ -83,8 +84,36 @@ typedef struct _xf86SigIOFunc {
static Xf86SigIOFunc xf86SigIOFuncs[MAX_FUNCS]; static Xf86SigIOFunc xf86SigIOFuncs[MAX_FUNCS];
static int xf86SigIOMax; static int xf86SigIOMax;
static int xf86SigIOMaxFd; static struct pollfd *xf86SigIOFds;
static fd_set xf86SigIOMask; 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 * SIGIO gives no way of discovering which fd signalled, select
@ -93,24 +122,22 @@ static fd_set xf86SigIOMask;
static void static void
xf86SIGIO(int sig) xf86SIGIO(int sig)
{ {
int i; int i, f;
fd_set ready;
struct timeval to;
int save_errno = errno; /* do not clobber the global errno */ int save_errno = errno; /* do not clobber the global errno */
int r; int r;
inSignalContext = TRUE; inSignalContext = TRUE;
ready = xf86SigIOMask; SYSCALL(r = poll(xf86SigIOFds, xf86SigIONum, 0));
to.tv_sec = 0; for (f = 0; r > 0 && f < xf86SigIONum; f++) {
to.tv_usec = 0; if (xf86SigIOFds[f].revents & POLLIN) {
SYSCALL(r = select(xf86SigIOMaxFd, &ready, 0, 0, &to)); for (i = 0; i < xf86SigIOMax; i++)
for (i = 0; r > 0 && i < xf86SigIOMax; i++) if (xf86SigIOFuncs[i].f && xf86SigIOFuncs[i].fd == xf86SigIOFds[f].fd)
if (xf86SigIOFuncs[i].f && FD_ISSET(xf86SigIOFuncs[i].fd, &ready)) { (*xf86SigIOFuncs[i].f) (xf86SigIOFuncs[i].fd,
(*xf86SigIOFuncs[i].f) (xf86SigIOFuncs[i].fd, xf86SigIOFuncs[i].closure);
xf86SigIOFuncs[i].closure);
r--; r--;
} }
}
if (r > 0) { if (r > 0) {
xf86Msg(X_ERROR, "SIGIO %d descriptors not handled\n", r); 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; xf86SigIOFuncs[i].f = f;
if (i >= xf86SigIOMax) if (i >= xf86SigIOMax)
xf86SigIOMax = i + 1; xf86SigIOMax = i + 1;
if (fd >= xf86SigIOMaxFd) xf86SigIOAdd(fd);
xf86SigIOMaxFd = fd + 1;
FD_SET(fd, &xf86SigIOMask);
release_sigio(); release_sigio();
return 1; return 1;
} }
@ -229,14 +254,12 @@ xf86RemoveSIGIOHandler(int fd)
struct sigaction osa; struct sigaction osa;
int i; int i;
int max; int max;
int maxfd;
int ret; int ret;
if (!xf86Info.useSIGIO) if (!xf86Info.useSIGIO)
return 0; return 0;
max = 0; max = 0;
maxfd = -1;
ret = 0; ret = 0;
for (i = 0; i < MAX_FUNCS; i++) { for (i = 0; i < MAX_FUNCS; i++) {
if (xf86SigIOFuncs[i].f) { if (xf86SigIOFuncs[i].f) {
@ -244,13 +267,11 @@ xf86RemoveSIGIOHandler(int fd)
xf86SigIOFuncs[i].f = 0; xf86SigIOFuncs[i].f = 0;
xf86SigIOFuncs[i].fd = 0; xf86SigIOFuncs[i].fd = 0;
xf86SigIOFuncs[i].closure = 0; xf86SigIOFuncs[i].closure = 0;
FD_CLR(fd, &xf86SigIOMask); xf86SigIORemove(fd);
ret = 1; ret = 1;
} }
else { else {
max = i + 1; max = i + 1;
if (xf86SigIOFuncs[i].fd >= maxfd)
maxfd = xf86SigIOFuncs[i].fd + 1;
} }
} }
} }
@ -267,7 +288,6 @@ xf86RemoveSIGIOHandler(int fd)
} }
#endif #endif
xf86SigIOMax = max; xf86SigIOMax = max;
xf86SigIOMaxFd = maxfd;
if (!max) { if (!max) {
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGIO); sigaddset(&sa.sa_mask, SIGIO);