[PATCH xserver 21/25] os: Use poll(2) for input thread

Keith Packard keithp at keithp.com
Wed May 25 05:38:58 UTC 2016


Replace use of select(2) to avoid fd limits

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 os/inputthread.c | 34 +++++++++++++++-------------------
 os/osdep.h       |  3 +++
 os/utils.c       | 11 +++++++++++
 3 files changed, 29 insertions(+), 19 deletions(-)

diff --git a/os/inputthread.c b/os/inputthread.c
index f4a4bde..60bff64 100644
--- a/os/inputthread.c
+++ b/os/inputthread.c
@@ -35,7 +35,6 @@
 #include <unistd.h>
 #include <pthread.h>
 
-#include <X11/Xpoll.h>
 #include "inputstr.h"
 #include "opaque.h"
 #include "osdep.h"
@@ -62,7 +61,7 @@ typedef struct _InputThreadDevice {
 typedef struct {
     pthread_t thread;
     struct xorg_list devs;
-    fd_set fds;
+    struct ospoll fds;
     int readPipe;
     int writePipe;
 } InputThreadInfo;
@@ -126,9 +125,10 @@ InputThreadFillPipe(int writeHead)
 {
     int ret;
     char byte = 0;
-    fd_set writePipe;
+    struct pollfd poll_fd;
 
-    FD_ZERO(&writePipe);
+    poll_fd.fd = writeHead;
+    poll_fd.events = POLLOUT;
 
     while (1) {
         ret = write(writeHead, &byte, 1);
@@ -141,8 +141,7 @@ InputThreadFillPipe(int writeHead)
             FatalError("input-thread: filling pipe");
 
         DebugF("input-thread: pipe full\n");
-        FD_SET(writeHead, &writePipe);
-        Select(writeHead + 1, NULL, &writePipe, NULL, NULL);
+        poll(&poll_fd, 1, -1);
     }
 }
 
@@ -198,7 +197,8 @@ InputThreadRegisterDev(int fd,
 
     xorg_list_add(&dev->node, &inputThreadInfo->devs);
 
-    FD_SET(fd, &inputThreadInfo->fds);
+    ospoll_fd_add(&inputThreadInfo->fds, fd);
+    ospoll_fd_listen(&inputThreadInfo->fds, fd, POLLIN);
 
     InputThreadFillPipe(hotplugPipeWrite);
     DebugF("input-thread: registered device %d\n", fd);
@@ -239,7 +239,7 @@ InputThreadUnregisterDev(int fd)
 
     xorg_list_del(&dev->node);
 
-    FD_CLR(fd, &inputThreadInfo->fds);
+    ospoll_fd_remove(&inputThreadInfo->fds, fd);
     free(dev);
 
     InputThreadFillPipe(hotplugPipeWrite);
@@ -265,19 +265,15 @@ InputThreadUnregisterDev(int fd)
 static void*
 InputThreadDoWork(void *arg)
 {
-    fd_set readyFds;
     InputThreadDevice *dev, *next;
 
-    FD_ZERO(&readyFds);
-
     while (1)
     {
-        XFD_COPYSET(&inputThreadInfo->fds, &readyFds);
-        FD_SET(hotplugPipeRead, &readyFds);
+        ospoll_fd_add(&inputThreadInfo->fds, hotplugPipeRead);
 
         DebugF("input-thread: %s waiting for devices\n", __func__);
 
-        if (Select(MAXSELECT, &readyFds, NULL, NULL, NULL) < 0) {
+        if (poll(inputThreadInfo->fds.fds, inputThreadInfo->fds.num, -1) < 0) {
             if (errno == EINVAL)
                 FatalError("input-thread: %s (%s)", __func__, strerror(errno));
             else if (errno != EINTR)
@@ -288,7 +284,7 @@ InputThreadDoWork(void *arg)
 
         /* Call the device drivers to generate input events for us */
         xorg_list_for_each_entry_safe(dev, next, &inputThreadInfo->devs, node) {
-            if (FD_ISSET(dev->fd, &readyFds) && dev->readInputProc) {
+            if (ospoll_fd_revents(&inputThreadInfo->fds, dev->fd) & POLLIN) {
                 input_lock();
                 dev->readInputProc(dev->fd, X_NOTIFY_READ, dev->readInputArgs);
                 input_unlock();
@@ -300,7 +296,7 @@ InputThreadDoWork(void *arg)
         InputThreadFillPipe(inputThreadInfo->writePipe);
 
         /* Empty pending input, shut down if the pipe has been closed */
-        if (FD_ISSET(hotplugPipeRead, &readyFds)) {
+        if (ospoll_fd_revents(&inputThreadInfo->fds, hotplugPipeRead) & POLLIN) {
             if (InputThreadReadPipe(hotplugPipeRead) == 0)
                 break;
         }
@@ -338,7 +334,7 @@ InputThreadPreInit(void)
 
     inputThreadInfo->thread = 0;
     xorg_list_init(&inputThreadInfo->devs);
-    FD_ZERO(&inputThreadInfo->fds);
+    ospoll_fd_init(&inputThreadInfo->fds);
 
     /* By making read head non-blocking, we ensure that while the main thread
      * is busy servicing client requests, the dedicated input thread can work
@@ -407,11 +403,11 @@ InputThreadFini(void)
     pthread_join(inputThreadInfo->thread, NULL);
 
     xorg_list_for_each_entry_safe(dev, next, &inputThreadInfo->devs, node) {
-        FD_CLR(dev->fd, &inputThreadInfo->fds);
+        ospoll_fd_remove(&inputThreadInfo->fds, dev->fd);
         free(dev);
     }
     xorg_list_init(&inputThreadInfo->devs);
-    FD_ZERO(&inputThreadInfo->fds);
+    ospoll_fd_init(&inputThreadInfo->fds);
 
     RemoveNotifyFd(inputThreadInfo->readPipe);
     close(inputThreadInfo->readPipe);
diff --git a/os/osdep.h b/os/osdep.h
index 528cf8a..ec8158e 100644
--- a/os/osdep.h
+++ b/os/osdep.h
@@ -194,6 +194,9 @@ ospoll_fd_listen(struct ospoll *ospoll, int fd, short events);
 void
 ospoll_fd_mute(struct ospoll *ospoll, int fd, short events);
 
+short
+ospoll_fd_revents(struct ospoll *ospoll, int fd);
+
 #if !defined(WIN32) || defined(__CYGWIN__)
 extern int *ConnectionTranslation;
 #else
diff --git a/os/utils.c b/os/utils.c
index b5195d9..a2cb03c 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -2220,3 +2220,14 @@ ospoll_fd_mute(struct ospoll *ospoll, int fd, short events)
 
     ospoll->fds[pos].events &= ~events;
 }
+
+short
+ospoll_fd_revents(struct ospoll *ospoll, int fd)
+{
+    int pos = ospoll_fd_find(ospoll, fd);
+
+    if (pos < 0)
+        return 0;
+
+    return ospoll->fds[pos].revents;
+}
-- 
2.8.0.rc3



More information about the xorg-devel mailing list