mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-31 00:32:53 +00:00
Merge pull request #12335 from Tilka/evdev
evdev: close file descriptors in a separate thread
This commit is contained in:
commit
db0cd82326
@ -21,6 +21,7 @@
|
|||||||
#include "Common/ScopeGuard.h"
|
#include "Common/ScopeGuard.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
#include "Common/Thread.h"
|
#include "Common/Thread.h"
|
||||||
|
#include "Common/WorkQueueThread.h"
|
||||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||||
|
|
||||||
namespace ciface::evdev
|
namespace ciface::evdev
|
||||||
@ -34,6 +35,12 @@ public:
|
|||||||
|
|
||||||
void RemoveDevnodeObject(const std::string&);
|
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:
|
private:
|
||||||
std::shared_ptr<evdevDevice>
|
std::shared_ptr<evdevDevice>
|
||||||
FindDeviceWithUniqueIDAndPhysicalLocation(const char* unique_id, const char* physical_location);
|
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
|
// as devices can be destroyed by any thread at any time. As of now it's protected
|
||||||
// by ControllerInterface::m_devices_population_mutex.
|
// by ControllerInterface::m_devices_population_mutex.
|
||||||
std::map<std::string, std::weak_ptr<evdevDevice>> m_devnode_objects;
|
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)
|
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)
|
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
|
// This usually fails because the device node isn't an evdev device, such as /dev/input/js0
|
||||||
close(fd);
|
CloseDescriptor(fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,7 +424,7 @@ void InputBackend::StopHotplugThread()
|
|||||||
}
|
}
|
||||||
|
|
||||||
InputBackend::InputBackend(ControllerInterface* controller_interface)
|
InputBackend::InputBackend(ControllerInterface* controller_interface)
|
||||||
: ciface::InputBackend(controller_interface)
|
: ciface::InputBackend(controller_interface), m_cleanup_thread("evdev cleanup", close)
|
||||||
{
|
{
|
||||||
StartHotplugThread();
|
StartHotplugThread();
|
||||||
}
|
}
|
||||||
@ -665,7 +674,7 @@ evdevDevice::~evdevDevice()
|
|||||||
{
|
{
|
||||||
m_input_backend.RemoveDevnodeObject(node.devnode);
|
m_input_backend.RemoveDevnodeObject(node.devnode);
|
||||||
libevdev_free(node.device);
|
libevdev_free(node.device);
|
||||||
close(node.fd);
|
m_input_backend.CloseDescriptor(node.fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user