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 d3e4fcf8b7)
This commit is contained in:
Camilla Löwy 2022-02-01 22:05:55 +01:00
parent 54f2a865e9
commit ca1a98e7a2
3 changed files with 15 additions and 18 deletions

View File

@ -81,6 +81,7 @@ video tutorials.
- Paul Holden - Paul Holden
- Warren Hu - Warren Hu
- Charles Huber - Charles Huber
- illustris
- InKryption - InKryption
- IntellectualKitty - IntellectualKitty
- Aaron Jacobs - Aaron Jacobs

View File

@ -125,6 +125,8 @@ information on what to include when reporting a bug.
- [Cocoa] Bugfix: `kUTTypeURL` was deprecated in macOS 12.0 (#2003) - [Cocoa] Bugfix: `kUTTypeURL` was deprecated in macOS 12.0 (#2003)
- [X11] Bugfix: Dynamic loading on OpenBSD failed due to soname differences - [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] Added support for key names via xkbcommon
- [Wayland] Bugfix: Key repeat could lead to a race condition (#1710) - [Wayland] Bugfix: Key repeat could lead to a race condition (#1710)
- [Wayland] Bugfix: Activating a window would emit two input focus events - [Wayland] Bugfix: Activating a window would emit two input focus events

View File

@ -32,7 +32,7 @@
#include <X11/cursorfont.h> #include <X11/cursorfont.h>
#include <X11/Xmd.h> #include <X11/Xmd.h>
#include <sys/select.h> #include <poll.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@ -57,37 +57,31 @@
#define _GLFW_XDND_VERSION 5 #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 // This avoids blocking other threads via the per-display Xlib lock that also
// covers GLX functions // covers GLX functions
// //
static GLFWbool waitForEvent(double* timeout) 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 (;;) for (;;)
{ {
FD_ZERO(&fds); nfds_t count = 1;
FD_SET(fd, &fds); struct pollfd fds[2] =
{
{ ConnectionNumber(_glfw.x11.display), POLLIN }
};
#if defined(__linux__) #if defined(__linux__)
if (_glfw.linjs.inotify > 0) if (_glfw.linjs.inotify > 0)
FD_SET(_glfw.linjs.inotify, &fds); fds[count++] = (struct pollfd) { _glfw.linjs.inotify, POLLIN };
#endif #endif
if (timeout) if (timeout)
{ {
const long seconds = (long) *timeout; const int milliseconds = (int) (*timeout * 1e3);
const long microseconds = (long) ((*timeout - seconds) * 1e6);
struct timeval tv = { seconds, microseconds };
const uint64_t base = _glfwPlatformGetTimerValue(); 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; const int error = errno;
*timeout -= (_glfwPlatformGetTimerValue() - base) / *timeout -= (_glfwPlatformGetTimerValue() - base) /
@ -98,7 +92,7 @@ static GLFWbool waitForEvent(double* timeout)
if ((result == -1 && error == EINTR) || *timeout <= 0.0) if ((result == -1 && error == EINTR) || *timeout <= 0.0)
return GLFW_FALSE; 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; return GLFW_TRUE;
} }
} }