diff options
| author | Tillmann Karras <tilkax@gmail.com> | 2023-11-28 13:25:59 +0000 |
|---|---|---|
| committer | Tillmann Karras <tilkax@gmail.com> | 2024-04-06 20:58:17 +0100 |
| commit | d1db347c8af0a0c609736a4db05d62304c3f3220 (patch) | |
| tree | 1d30dddbf94faae82fdb2760c9870a73c9782549 /Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp | |
| parent | 116da3ab956ed02043cd944a76ea05f828965fef (diff) | |
evdev: close file descriptors in a separate thread
For some reason Linux is surprisingly slow at closing file descriptors
of event devices. This commit improves GUI startup times on my computer
by about 1.5 seconds.
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp')
| -rw-r--r-- | Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp index 6e9764fda9..e9f4f21980 100644 --- a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp +++ b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp @@ -21,6 +21,7 @@ #include "Common/ScopeGuard.h" #include "Common/StringUtil.h" #include "Common/Thread.h" +#include "Common/WorkQueueThread.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" namespace ciface::evdev @@ -34,6 +35,12 @@ public: void RemoveDevnodeObject(const std::string&); + // Linux has the strange behavior that closing file descriptors of event devices can be + // surprisingly slow, in the range of 20-70 milliseconds. For modern systems that have maybe 30 + // event devices this can quickly add up, leading to visibly slow startup. So we close FDs on a + // separate thread *shrug* + void CloseDescriptor(int fd) { m_cleanup_thread.Push(fd); } + private: std::shared_ptr<evdevDevice> FindDeviceWithUniqueIDAndPhysicalLocation(const char* unique_id, const char* physical_location); @@ -55,6 +62,8 @@ private: // as devices can be destroyed by any thread at any time. As of now it's protected // by ControllerInterface::m_devices_population_mutex. std::map<std::string, std::weak_ptr<evdevDevice>> m_devnode_objects; + + Common::WorkQueueThread<int> m_cleanup_thread; }; std::unique_ptr<ciface::InputBackend> CreateInputBackend(ControllerInterface* controller_interface) @@ -273,7 +282,7 @@ void InputBackend::AddDeviceNode(const char* devnode) if (libevdev_new_from_fd(fd, &dev) != 0) { // This usually fails because the device node isn't an evdev device, such as /dev/input/js0 - close(fd); + CloseDescriptor(fd); return; } @@ -415,7 +424,7 @@ void InputBackend::StopHotplugThread() } InputBackend::InputBackend(ControllerInterface* controller_interface) - : ciface::InputBackend(controller_interface) + : ciface::InputBackend(controller_interface), m_cleanup_thread("evdev cleanup", close) { StartHotplugThread(); } @@ -665,7 +674,7 @@ evdevDevice::~evdevDevice() { m_input_backend.RemoveDevnodeObject(node.devnode); libevdev_free(node.device); - close(node.fd); + m_input_backend.CloseDescriptor(node.fd); } } |
