Replace use of select(2) to avoid fd limits Signed-off-by: Keith Packard <kei...@keithp.com> --- os/inputthread.c | 85 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 37 deletions(-)
diff --git a/os/inputthread.c b/os/inputthread.c index b6bbf35..3d8e6da 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); } } @@ -167,6 +166,18 @@ InputThreadReadPipe(int readHead) return 1; } +static void +InputReady(int fd, short revents, void *data) +{ + InputThreadDevice *dev = data; + + if (revents & POLLIN) { + input_lock(); + dev->readInputProc(fd, X_NOTIFY_READ, dev->readInputArgs); + input_unlock(); + } +} + /** * Register an input device in the threaded input facility * @@ -198,7 +209,11 @@ InputThreadRegisterDev(int fd, xorg_list_add(&dev->node, &inputThreadInfo->devs); - FD_SET(fd, &inputThreadInfo->fds); + ospoll_add(inputThreadInfo->fds, fd, + ospoll_trigger_level, + InputReady, + dev); + ospoll_listen(inputThreadInfo->fds, fd, POLLIN); InputThreadFillPipe(hotplugPipeWrite); DebugF("input-thread: registered device %d\n", fd); @@ -239,7 +254,7 @@ InputThreadUnregisterDev(int fd) xorg_list_del(&dev->node); - FD_CLR(fd, &inputThreadInfo->fds); + ospoll_remove(inputThreadInfo->fds, fd); free(dev); InputThreadFillPipe(hotplugPipeWrite); @@ -248,6 +263,16 @@ InputThreadUnregisterDev(int fd) return 1; } +static void +InputThreadPipeNotify(int fd, short revents, void *data) +{ + /* Empty pending input, shut down if the pipe has been closed */ + if (InputThreadReadPipe(hotplugPipeRead) == 0) { + Bool *running = data; + *running = FALSE; + } +} + /** * The workhorse of threaded input event generation. * @@ -265,51 +290,36 @@ InputThreadUnregisterDev(int fd) static void* InputThreadDoWork(void *arg) { - fd_set readyFds; - InputThreadDevice *dev, *next; + Bool running = TRUE; sigset_t set; /* Don't handle any signals on this thread */ sigfillset(&set); pthread_sigmask(SIG_BLOCK, &set, NULL); - FD_ZERO(&readyFds); + ospoll_add(inputThreadInfo->fds, hotplugPipeRead, + ospoll_trigger_level, + InputThreadPipeNotify, + &running); - while (1) + while (running) { - XFD_COPYSET(&inputThreadInfo->fds, &readyFds); - FD_SET(hotplugPipeRead, &readyFds); - DebugF("input-thread: %s waiting for devices\n", __func__); - if (Select(MAXSELECT, &readyFds, NULL, NULL, NULL) < 0) { + if (ospoll_wait(inputThreadInfo->fds, -1) < 0) { if (errno == EINVAL) FatalError("input-thread: %s (%s)", __func__, strerror(errno)); else if (errno != EINTR) ErrorF("input-thread: %s (%s)\n", __func__, strerror(errno)); } - DebugF("input-thread: %s generating events\n", __func__); - - /* 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) { - input_lock(); - dev->readInputProc(dev->fd, X_NOTIFY_READ, dev->readInputArgs); - input_unlock(); - } - } - /* Kick main thread to process the generated input events and drain * events from hotplug pipe */ InputThreadFillPipe(inputThreadInfo->writePipe); - - /* Empty pending input, shut down if the pipe has been closed */ - if (FD_ISSET(hotplugPipeRead, &readyFds)) { - if (InputThreadReadPipe(hotplugPipeRead) == 0) - break; - } } + + ospoll_remove(inputThreadInfo->fds, hotplugPipeRead); + return NULL; } @@ -343,7 +353,7 @@ InputThreadPreInit(void) inputThreadInfo->thread = 0; xorg_list_init(&inputThreadInfo->devs); - FD_ZERO(&inputThreadInfo->fds); + inputThreadInfo->fds = ospoll_create(); /* By making read head non-blocking, we ensure that while the main thread * is busy servicing client requests, the dedicated input thread can work @@ -351,7 +361,6 @@ InputThreadPreInit(void) */ inputThreadInfo->readPipe = fds[0]; fcntl(inputThreadInfo->readPipe, F_SETFL, O_NONBLOCK | O_CLOEXEC); - SetNotifyFd(inputThreadInfo->readPipe, InputThreadNotifyPipe, X_NOTIFY_READ, NULL); inputThreadInfo->writePipe = fds[1]; @@ -387,6 +396,8 @@ InputThreadInit(void) if (pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) != 0) ErrorF("input-thread: error setting thread scope\n"); + SetNotifyFd(inputThreadInfo->readPipe, InputThreadNotifyPipe, X_NOTIFY_READ, NULL); + DebugF("input-thread: creating thread\n"); pthread_create(&inputThreadInfo->thread, &attr, &InputThreadDoWork, NULL); @@ -412,11 +423,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_remove(inputThreadInfo->fds, dev->fd); free(dev); } xorg_list_init(&inputThreadInfo->devs); - FD_ZERO(&inputThreadInfo->fds); + ospoll_destroy(inputThreadInfo->fds); RemoveNotifyFd(inputThreadInfo->readPipe); close(inputThreadInfo->readPipe); -- 2.8.0.rc3 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel