USBv5: Fix racy device change behavior

This prevents the device changes happening between 2 GETDEVICECHANGE
calls from being missed by the application.
This commit is contained in:
Pablo Stebler 2022-03-14 22:32:30 +01:00
parent 905e86d754
commit 7e7b0971ab
No known key found for this signature in database
GPG Key ID: 90375E73AC6109CC
2 changed files with 9 additions and 5 deletions

View File

@ -85,7 +85,7 @@ struct DeviceEntry
void USBV5ResourceManager::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)
@ -119,11 +119,12 @@ std::optional<IPCReply> USBV5ResourceManager::GetDeviceChange(const IOCtlRequest
std::lock_guard lk{m_devicechange_hook_address_mutex};
m_devicechange_hook_request = std::make_unique<IOCtlRequest>(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;
}
@ -226,7 +227,10 @@ void USBV5ResourceManager::OnDeviceChangeEnd()
void USBV5ResourceManager::TriggerDeviceChangeReply()
{
if (!m_devicechange_hook_request)
{
m_has_pending_changes = true;
return;
}
std::lock_guard lock{m_usbv5_devices_mutex};
u8 num_devices = 0;

View File

@ -89,7 +89,7 @@ protected:
void TriggerDeviceChangeReply();
virtual bool HasInterfaceNumberInIDs() const = 0;
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;