From ae17a06cf85baa09d9537fa0c1b5d5b8a50f9187 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 5 Feb 2026 23:16:05 -0600 Subject: [PATCH] ControllerInterface/evdev: Replace a select() call with poll(). select() should not be used on Linux. "select() can monitor only file descriptors numbers that are less than FD_SETSIZE". --- .../ControllerInterface/evdev/evdev.cpp | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp index bb51d0026e..6528ffd197 100644 --- a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp +++ b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "Common/Assert.h" @@ -21,6 +22,7 @@ #include "Common/ScopeGuard.h" #include "Common/StringUtil.h" #include "Common/Thread.h" +#include "Common/UnixUtil.h" #include "Common/WorkQueueThread.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" @@ -343,15 +345,19 @@ void InputBackend::HotplugThreadFunc() while (m_hotplug_thread_running.IsSet()) { - fd_set fds; + std::array pollfds{ + pollfd{.fd = monitor_fd, .events = POLLIN}, + pollfd{.fd = m_wakeup_eventfd, .events = POLLIN}, + }; - FD_ZERO(&fds); - FD_SET(monitor_fd, &fds); - FD_SET(m_wakeup_eventfd, &fds); + const int poll_result = UnixUtil::RetryOnEINTR(poll, pollfds.data(), pollfds.size(), -1); + if (poll_result < 0) + { + ERROR_LOG_FMT(CONTROLLERINTERFACE, "evdev: poll: {}", Common::LastStrerrorString()); + break; + } - const int ret = - select(std::max(monitor_fd, m_wakeup_eventfd) + 1, &fds, nullptr, nullptr, nullptr); - if (ret < 1 || !FD_ISSET(monitor_fd, &fds)) + if (pollfds[0].revents == 0) continue; udev_device* const dev = udev_monitor_receive_device(monitor); @@ -401,8 +407,7 @@ void InputBackend::StartHotplugThread() return; } - m_wakeup_eventfd = eventfd(0, 0); - ASSERT_MSG(CONTROLLERINTERFACE, m_wakeup_eventfd != -1, "Couldn't create eventfd."); + m_wakeup_eventfd = UnixUtil::CreateEventFD(0, 0); m_hotplug_thread = std::thread(&InputBackend::HotplugThreadFunc, this); } @@ -415,7 +420,7 @@ void InputBackend::StopHotplugThread() return; } - // Write something to efd so that select() stops blocking. + // Write something to efd so that poll() stops blocking. const uint64_t value = 1; static_cast(!write(m_wakeup_eventfd, &value, sizeof(uint64_t)));