summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerInterface
diff options
context:
space:
mode:
authorFiloppi <filippotarpini@hotmail.it>2021-05-15 12:08:38 +0300
committerFiloppi <filippotarpini@hotmail.it>2021-06-07 11:07:05 +0300
commitc238e4911916e2a90e2e324873e0da4907d243c3 (patch)
tree47ddda7e8ccb19b7fd43e28ccd05a135dd193b5b /Source/Core/InputCommon/ControllerInterface
parent2376aec135d957ee74bd2be1d587539dea4d5dab (diff)
ControllerInterface: Remove OSX window handle
also make it more thread safe (avoid rare deadlock) and fix it trying to add devices before the CI has init
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface')
-rw-r--r--Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp21
-rw-r--r--Source/Core/InputCommon/ControllerInterface/ControllerInterface.h1
-rw-r--r--Source/Core/InputCommon/ControllerInterface/OSX/OSX.h3
-rw-r--r--Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm26
4 files changed, 29 insertions, 22 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp
index 54974aed7a..b84e8af571 100644
--- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp
+++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp
@@ -64,9 +64,7 @@ void ControllerInterface::Initialize(const WindowSystemInfo& wsi)
// nothing needed
#endif
#ifdef CIFACE_USE_OSX
- if (m_wsi.type == WindowSystemType::MacOS)
- ciface::OSX::Init(wsi.render_window);
-// nothing needed for Quartz
+// nothing needed for OSX and Quartz
#endif
#ifdef CIFACE_USE_SDL
ciface::SDL::Init();
@@ -118,6 +116,18 @@ void ControllerInterface::RefreshDevices(RefreshReason reason)
if (!m_is_init)
return;
+#ifdef CIFACE_USE_OSX
+ if (m_wsi.type == WindowSystemType::MacOS)
+ {
+ std::lock_guard lk_pre_population(m_pre_population_mutex);
+ // This is needed to stop its threads before locking our mutexes, to avoid deadlocks
+ // (in case it tried to add a device after we had locked m_devices_population_mutex).
+ // There doesn't seem to be an easy to way to repopulate OSX devices without restarting
+ // its hotplug thread. This will not release its devices, that's still done below.
+ ciface::OSX::DeInit();
+ }
+#endif
+
// This lock has two main functions:
// -Avoid a deadlock between m_devices_mutex and ControllerEmu::s_state_mutex when
// InvokeDevicesChangedCallbacks() is called concurrently by two different threads.
@@ -152,7 +162,10 @@ void ControllerInterface::RefreshDevices(RefreshReason reason)
#ifdef CIFACE_USE_OSX
if (m_wsi.type == WindowSystemType::MacOS)
{
- ciface::OSX::PopulateDevices(m_wsi.render_window);
+ {
+ std::lock_guard lk_pre_population(m_pre_population_mutex);
+ ciface::OSX::Init();
+ }
ciface::Quartz::PopulateDevices(m_wsi.render_window);
}
#endif
diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h
index 826659941d..9c91d853e7 100644
--- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h
+++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h
@@ -116,6 +116,7 @@ private:
std::list<std::function<void()>> m_devices_changed_callbacks;
mutable std::recursive_mutex m_devices_population_mutex;
+ mutable std::mutex m_pre_population_mutex;
mutable std::mutex m_callbacks_mutex;
std::atomic<bool> m_is_init;
// This is now always protected by m_devices_population_mutex, so
diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h
index 955b426f5e..f4ebc1a911 100644
--- a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h
+++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h
@@ -6,8 +6,7 @@
namespace ciface::OSX
{
-void Init(void* window);
-void PopulateDevices(void* window);
+void Init();
void DeInit();
void DeviceElementDebugPrint(const void*, void*);
diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm
index 63bddf499e..8c80e9f529 100644
--- a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm
+++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm
@@ -135,8 +135,6 @@ static void DeviceDebugPrint(IOHIDDeviceRef device)
#endif
}
-static void* g_window;
-
static std::string GetDeviceRefName(IOHIDDeviceRef inIOHIDDeviceRef)
{
const NSString* name = reinterpret_cast<const NSString*>(
@@ -172,10 +170,8 @@ static void DeviceMatchingCallback(void* inContext, IOReturn inResult, void* inS
}
}
-void Init(void* window)
+void Init()
{
- g_window = window;
-
HIDManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
if (!HIDManager)
ERROR_LOG_FMT(CONTROLLERINTERFACE, "Failed to create HID Manager reference");
@@ -210,19 +206,17 @@ void Init(void* window)
});
}
-void PopulateDevices(void* window)
-{
- DeInit();
- Init(window);
-}
-
void DeInit()
{
- s_stopper.Signal();
- s_hotplug_thread.join();
+ if (HIDManager)
+ {
+ s_stopper.Signal();
+ s_hotplug_thread.join();
- // This closes all devices as well
- IOHIDManagerClose(HIDManager, kIOHIDOptionsTypeNone);
- CFRelease(HIDManager);
+ // This closes all devices as well
+ IOHIDManagerClose(HIDManager, kIOHIDOptionsTypeNone);
+ CFRelease(HIDManager);
+ HIDManager = nullptr;
+ }
}
} // namespace ciface::OSX