summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/GCAdapter.cpp
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2019-06-25 17:31:35 +0200
committerLéo Lam <leo@leolam.fr>2019-06-26 17:55:51 +0200
commitcf60a9a7f77f78d4cd9de08cdbe93e0236794a5b (patch)
tree957bcb1d908ff5c44c7420ba288f0dd2496bcdbb /Source/Core/InputCommon/GCAdapter.cpp
parent769ba43abf3afc0f65dfa610236636e80371d3ca (diff)
Use separate libusb contexts to avoid thread safety issues
Unfortunately, it appears that using libusb's synchronous transfer API from several threads causes nasty race conditions in event handling and can lead to deadlocks, despite the fact that libusb's synchronous API is documented to be perfectly fine to use from several threads (only the manual polling functionality is supposed to require special precautions). Since usbdk was the only real reason for using a single libusb context and since usbdk (currently) has so many issues with Dolphin, I think dropping support for it in order to fix other backends is acceptable.
Diffstat (limited to 'Source/Core/InputCommon/GCAdapter.cpp')
-rw-r--r--Source/Core/InputCommon/GCAdapter.cpp13
1 files changed, 7 insertions, 6 deletions
diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp
index 493d8003f2..f54f85393c 100644
--- a/Source/Core/InputCommon/GCAdapter.cpp
+++ b/Source/Core/InputCommon/GCAdapter.cpp
@@ -72,6 +72,8 @@ static bool s_libusb_hotplug_enabled = false;
static libusb_hotplug_callback_handle s_hotplug_handle;
#endif
+static LibusbUtils::Context s_libusb_context;
+
static u8 s_endpoint_in = 0;
static u8 s_endpoint_out = 0;
@@ -147,7 +149,6 @@ static int HotplugCallback(libusb_context* ctx, libusb_device* dev, libusb_hotpl
static void ScanThreadFunc()
{
- auto& context = LibusbUtils::GetContext();
Common::SetCurrentThreadName("GC Adapter Scanning Thread");
NOTICE_LOG(SERIALINTERFACE, "GC Adapter scanning thread started");
@@ -158,7 +159,7 @@ static void ScanThreadFunc()
if (s_libusb_hotplug_enabled)
{
if (libusb_hotplug_register_callback(
- context,
+ s_libusb_context,
(libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
LIBUSB_HOTPLUG_ENUMERATE, 0x057e, 0x0337, LIBUSB_HOTPLUG_MATCH_ANY, HotplugCallback,
@@ -212,7 +213,7 @@ void StartScanThread()
{
if (s_adapter_detect_thread_running.IsSet())
return;
- if (!LibusbUtils::GetContext().IsValid())
+ if (!s_libusb_context.IsValid())
return;
s_adapter_detect_thread_running.Set(true);
s_adapter_detect_thread = std::thread(ScanThreadFunc);
@@ -240,7 +241,7 @@ static void Setup()
s_controller_rumble[i] = 0;
}
- LibusbUtils::GetContext().GetDeviceList([](libusb_device* device) {
+ s_libusb_context.GetDeviceList([](libusb_device* device) {
if (CheckDeviceAccess(device))
{
// Only connect to a single adapter in case the user has multiple connected
@@ -364,8 +365,8 @@ void Shutdown()
{
StopScanThread();
#if defined(LIBUSB_API_VERSION) && LIBUSB_API_VERSION >= 0x01000102
- if (LibusbUtils::GetContext().IsValid() && s_libusb_hotplug_enabled)
- libusb_hotplug_deregister_callback(LibusbUtils::GetContext(), s_hotplug_handle);
+ if (s_libusb_context.IsValid() && s_libusb_hotplug_enabled)
+ libusb_hotplug_deregister_callback(s_libusb_context, s_hotplug_handle);
#endif
Reset();