From 2b44e1b851175f986ae8f7d51457a4d23fc609d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 4 May 2019 12:23:57 +0200 Subject: [PATCH] IOS/USB: Fix initial device scan Even though libusb is supposed to be thread-safe, in practice it's not (at least on Windows); getting a list of devices from two different threads can result in libusb crashes. This is easily fixed by waiting for the scan thread to complete scanning instead of running the scan on the CPU thread. This also fixes an issue that I had overlooked in the initial implementation: IOS interfaces such as OH0 are sometimes opened every frame, in which case we were doing a full device scan every single frame on the CPU thread! --- Source/Core/Core/IOS/USB/Host.cpp | 11 +++++++---- Source/Core/Core/IOS/USB/Host.h | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/IOS/USB/Host.cpp b/Source/Core/Core/IOS/USB/Host.cpp index 9b97078cd4..03b9c30c62 100644 --- a/Source/Core/Core/IOS/USB/Host.cpp +++ b/Source/Core/Core/IOS/USB/Host.cpp @@ -45,12 +45,14 @@ USBHost::~USBHost() IPCCommandResult USBHost::Open(const OpenRequest& request) { - // Force a device scan to complete, because some games (including Your Shape) only care - // about the initial device list (in the first GETDEVICECHANGE reply). - while (!UpdateDevices()) + if (!m_has_initialised) { + StartThreads(); + // Force a device scan to complete, because some games (including Your Shape) only care + // about the initial device list (in the first GETDEVICECHANGE reply). + m_first_scan_complete_event.Wait(); + m_has_initialised = true; } - StartThreads(); return GetDefaultReply(IPC_SUCCESS); } @@ -117,6 +119,7 @@ bool USBHost::UpdateDevices(const bool always_add_hooks) return false; DetectRemovedDevices(plugged_devices, hooks); DispatchHooks(hooks); + m_first_scan_complete_event.Set(); return true; } diff --git a/Source/Core/Core/IOS/USB/Host.h b/Source/Core/Core/IOS/USB/Host.h index 4555b0f88a..dc37efe4c6 100644 --- a/Source/Core/Core/IOS/USB/Host.h +++ b/Source/Core/Core/IOS/USB/Host.h @@ -15,6 +15,7 @@ #include #include "Common/CommonTypes.h" +#include "Common/Event.h" #include "Common/Flag.h" #include "Core/IOS/Device.h" #include "Core/IOS/IOS.h" @@ -76,5 +77,7 @@ private: // Device scanning thread Common::Flag m_scan_thread_running; std::thread m_scan_thread; + Common::Event m_first_scan_complete_event; + bool m_has_initialised = false; }; } // namespace IOS::HLE::Device