[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