From ca1a98e7a2d4e029fa3ece888221d9c23a093ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 1 Feb 2022 22:05:55 +0100 Subject: [PATCH] X11: Fix event polling when event fd > 1023 This replaces select with poll for checking for data on event file descriptors, as select cannot handle file descriptors larger than 1023. Closes #2024 (cherry picked from commit d3e4fcf8b7608e7b6f6cf1c102b1e28c478f5a6c) --- CONTRIBUTORS.md | 1 + README.md | 2 ++ src/x11_window.c | 30 ++++++++++++------------------ 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 4526e5b2..b35d2428 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -81,6 +81,7 @@ video tutorials. - Paul Holden - Warren Hu - Charles Huber + - illustris - InKryption - IntellectualKitty - Aaron Jacobs diff --git a/README.md b/README.md index d0deac37..da0fc03d 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,8 @@ information on what to include when reporting a bug. - [Cocoa] Bugfix: `kUTTypeURL` was deprecated in macOS 12.0 (#2003) - [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences + - [X11] Bugfix: Waiting for events would fail if file descriptor was too large + (#2024) - [Wayland] Added support for key names via xkbcommon - [Wayland] Bugfix: Key repeat could lead to a race condition (#1710) - [Wayland] Bugfix: Activating a window would emit two input focus events diff --git a/src/x11_window.c b/src/x11_window.c index 356572d8..f328c297 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include @@ -57,37 +57,31 @@ #define _GLFW_XDND_VERSION 5 -// Wait for data to arrive using select +// Wait for event data to arrive on any relevant file descriptor // This avoids blocking other threads via the per-display Xlib lock that also // covers GLX functions // static GLFWbool waitForEvent(double* timeout) { - fd_set fds; - const int fd = ConnectionNumber(_glfw.x11.display); - int count = fd + 1; - -#if defined(__linux__) - if (_glfw.linjs.inotify > fd) - count = _glfw.linjs.inotify + 1; -#endif for (;;) { - FD_ZERO(&fds); - FD_SET(fd, &fds); + nfds_t count = 1; + struct pollfd fds[2] = + { + { ConnectionNumber(_glfw.x11.display), POLLIN } + }; + #if defined(__linux__) if (_glfw.linjs.inotify > 0) - FD_SET(_glfw.linjs.inotify, &fds); + fds[count++] = (struct pollfd) { _glfw.linjs.inotify, POLLIN }; #endif if (timeout) { - const long seconds = (long) *timeout; - const long microseconds = (long) ((*timeout - seconds) * 1e6); - struct timeval tv = { seconds, microseconds }; + const int milliseconds = (int) (*timeout * 1e3); const uint64_t base = _glfwPlatformGetTimerValue(); - const int result = select(count, &fds, NULL, NULL, &tv); + const int result = poll(fds, count, milliseconds); const int error = errno; *timeout -= (_glfwPlatformGetTimerValue() - base) / @@ -98,7 +92,7 @@ static GLFWbool waitForEvent(double* timeout) if ((result == -1 && error == EINTR) || *timeout <= 0.0) return GLFW_FALSE; } - else if (select(count, &fds, NULL, NULL, NULL) != -1 || errno != EINTR) + else if (poll(fds, count, -1) != -1 || errno != EINTR) return GLFW_TRUE; } }