IOS: Add missing locking for USBHost::m_devices

Note: After adding the missing locking of m_devices_mutex, I had to move
the locking of m_hooks_mutex to avoid a random deadlock between the CPU
thread and USB scanning thread. (Either that or I would have to lock
m_devices_mutex before m_hooks_mutex.)
This commit is contained in:
JosJuice 2025-04-06 15:25:25 +02:00
parent 50a8ae9d90
commit 24fdcc1a0e

View file

@ -73,12 +73,15 @@ std::optional<IPCReply> OH0::IOCtlV(const IOCtlVRequest& request)
void OH0::DoState(PointerWrap& p)
{
{
std::lock_guard lk(m_devices_mutex);
if (p.IsReadMode() && !m_devices.empty())
{
Core::DisplayMessage("It is suggested that you unplug and replug all connected USB devices.",
5000);
Core::DisplayMessage("If USB doesn't work properly, an emulation reset may be needed.", 5000);
}
}
p.Do(m_insertion_hooks);
p.Do(m_removal_hooks);
p.Do(m_opened_devices);
@ -206,12 +209,12 @@ std::optional<IPCReply> OH0::RegisterInsertionHookWithID(const IOCtlVRequest& re
auto& system = GetSystem();
auto& memory = system.GetMemory();
std::lock_guard lock{m_hooks_mutex};
const u16 vid = memory.Read_U16(request.in_vectors[0].address);
const u16 pid = memory.Read_U16(request.in_vectors[1].address);
const bool trigger_only_for_new_device = memory.Read_U8(request.in_vectors[2].address) == 1;
if (!trigger_only_for_new_device && HasDeviceWithVidPid(vid, pid))
return IPCReply(IPC_SUCCESS);
std::lock_guard lock{m_hooks_mutex};
// TODO: figure out whether IOS allows more than one hook.
m_insertion_hooks.insert({{vid, pid}, request.address});
// The output vector is overwritten with an ID to use with ioctl 31 for cancelling the hook.
@ -231,6 +234,7 @@ std::optional<IPCReply> OH0::RegisterClassChangeHook(const IOCtlVRequest& reques
bool OH0::HasDeviceWithVidPid(const u16 vid, const u16 pid) const
{
std::lock_guard lk(m_devices_mutex);
return std::ranges::any_of(m_devices, [=](const auto& device) {
return device.second->GetVid() == vid && device.second->GetPid() == pid;
});