[PATCH xserver 23/25] xfree86: Switch from select(2) to poll(2)

Keith Packard keithp at keithp.com
Wed May 25 05:39:00 UTC 2016


xf86WaitForInput and the xf86 SIGIO handling code.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 hw/xfree86/common/xf86Events.c           |  1 -
 hw/xfree86/os-support/shared/posix_tty.c | 33 ++++++-----------
 hw/xfree86/os-support/shared/sigio.c     | 63 +++++++++++++++++++++-----------
 3 files changed, 52 insertions(+), 45 deletions(-)

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index b12766f..9a8f432 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -54,7 +54,6 @@
 #endif
 
 #include <X11/X.h>
-#include <X11/Xpoll.h>
 #include <X11/Xproto.h>
 #include <X11/Xatom.h>
 #include "misc.h"
diff --git a/hw/xfree86/os-support/shared/posix_tty.c b/hw/xfree86/os-support/shared/posix_tty.c
index 6e2af00..d5a70ba 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 <X11/X.h>
+#include <poll.h>
 #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 e0cd7a8..53ebacf 100644
--- a/hw/xfree86/os-support/shared/sigio.c
+++ b/hw/xfree86/os-support/shared/sigio.c
@@ -57,6 +57,7 @@
 #endif
 
 #include <X11/X.h>
+#include <poll.h>
 #include "xf86.h"
 #include "xf86Priv.h"
 #include "xf86_OSlib.h"
@@ -83,8 +84,35 @@ 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;
+    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 +121,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 +232,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);
             xf86ReleaseSIGIO();
             return 1;
         }
@@ -229,14 +253,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 +266,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 +287,6 @@ xf86RemoveSIGIOHandler(int fd)
         }
 #endif
         xf86SigIOMax = max;
-        xf86SigIOMaxFd = maxfd;
         if (!max) {
             sigemptyset(&sa.sa_mask);
             sigaddset(&sa.sa_mask, SIGIO);
-- 
2.8.0.rc3



More information about the xorg-devel mailing list