summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorPablo Stebler <pablo@stebler.xyz>2024-04-19 21:56:12 +0200
committerPablo Stebler <pablo@stebler.xyz>2024-04-19 21:56:12 +0200
commit93b29cb8b2fd76cfbf8d87541b37397f7bf1f9fe (patch)
treeb3650d3c0074d8ceb923c4f7d56f24482fd20be1 /Source/Core
parent1805f6e38158c90b9108895d42ca6cc37d0aeff7 (diff)
HIDv4: Fix racy device change behavior
This prevents the device changes happening between 2 GETDEVICECHANGE calls from being missed by the application. Same as 7e7b0971ab014467ce6c2fccdd29bc9070eb333c.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp12
-rw-r--r--Source/Core/Core/IOS/USB/USB_HID/HIDv4.h2
2 files changed, 9 insertions, 5 deletions
diff --git a/Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp b/Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp
index 1118599c4d..288c4490fc 100644
--- a/Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp
+++ b/Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp
@@ -94,11 +94,12 @@ std::optional<IPCReply> USB_HIDv4::GetDeviceChange(const IOCtlRequest& request)
return IPCReply(IPC_EINVAL);
m_devicechange_hook_request = std::make_unique<IOCtlRequest>(GetSystem(), request.address);
- // On the first call, the reply is sent immediately (instead of on device insertion/removal)
- if (m_devicechange_first_call)
+ // If there are pending changes, the reply is sent immediately (instead of on device
+ // insertion/removal).
+ if (m_has_pending_changes)
{
TriggerDeviceChangeReply();
- m_devicechange_first_call = false;
+ m_has_pending_changes = false;
}
return std::nullopt;
}
@@ -138,7 +139,7 @@ s32 USB_HIDv4::SubmitTransfer(USB::Device& device, const IOCtlRequest& request)
void USB_HIDv4::DoState(PointerWrap& p)
{
- p.Do(m_devicechange_first_call);
+ p.Do(m_has_pending_changes);
u32 hook_address = m_devicechange_hook_request ? m_devicechange_hook_request->address : 0;
p.Do(hook_address);
if (hook_address != 0)
@@ -199,7 +200,10 @@ bool USB_HIDv4::ShouldAddDevice(const USB::Device& device) const
void USB_HIDv4::TriggerDeviceChangeReply()
{
if (!m_devicechange_hook_request)
+ {
+ m_has_pending_changes = true;
return;
+ }
auto& system = GetSystem();
auto& memory = system.GetMemory();
diff --git a/Source/Core/Core/IOS/USB/USB_HID/HIDv4.h b/Source/Core/Core/IOS/USB/USB_HID/HIDv4.h
index 3fdd02fbab..44c8213ae0 100644
--- a/Source/Core/Core/IOS/USB/USB_HID/HIDv4.h
+++ b/Source/Core/Core/IOS/USB/USB_HID/HIDv4.h
@@ -44,7 +44,7 @@ private:
static constexpr u32 VERSION = 0x40001;
static constexpr u8 HID_CLASS = 0x03;
- bool m_devicechange_first_call = true;
+ bool m_has_pending_changes = true;
std::mutex m_devicechange_hook_address_mutex;
std::unique_ptr<IOCtlRequest> m_devicechange_hook_request;