Skip to content

Commit

Permalink
Merge pull request #12335 from Tilka/evdev
Browse files Browse the repository at this point in the history
evdev: close file descriptors in a separate thread
  • Loading branch information
jordan-woyak committed Apr 7, 2024
2 parents 116da3a + d1db347 commit db0cd82
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp
Expand Up @@ -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
Expand All @@ -34,6 +35,12 @@ class InputBackend final : public ciface::InputBackend

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);
Expand All @@ -55,6 +62,8 @@ class InputBackend final : public ciface::InputBackend
// 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)
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -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);
}
}

Expand Down

0 comments on commit db0cd82

Please sign in to comment.