Merge pull request #3805 from mathieui/gcadapter-unplug-crash
GCAdapter: improve thread safety
This commit is contained in:
commit
bb6604df76
|
@ -23,6 +23,9 @@ namespace GCAdapter
|
|||
{
|
||||
static bool CheckDeviceAccess(libusb_device* device);
|
||||
static void AddGCAdapter(libusb_device* device);
|
||||
static void ResetRumbleLockNeeded();
|
||||
static void Reset();
|
||||
static void Setup();
|
||||
|
||||
static bool s_detected = false;
|
||||
static libusb_device_handle* s_handle = nullptr;
|
||||
|
@ -38,6 +41,7 @@ static std::atomic<int> s_controller_payload_size = {0};
|
|||
static std::thread s_adapter_thread;
|
||||
static Common::Flag s_adapter_thread_running;
|
||||
|
||||
static std::mutex s_init_mutex;
|
||||
static std::thread s_adapter_detect_thread;
|
||||
static Common::Flag s_adapter_detect_thread_running;
|
||||
|
||||
|
@ -78,7 +82,10 @@ static int HotplugCallback(libusb_context* ctx, libusb_device* dev, libusb_hotpl
|
|||
if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)
|
||||
{
|
||||
if (s_handle == nullptr && CheckDeviceAccess(dev))
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(s_init_mutex);
|
||||
AddGCAdapter(dev);
|
||||
}
|
||||
}
|
||||
else if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
|
||||
{
|
||||
|
@ -116,6 +123,7 @@ static void ScanThreadFunc()
|
|||
{
|
||||
if (s_handle == nullptr)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(s_init_mutex);
|
||||
Setup();
|
||||
if (s_detected && s_detect_callback != nullptr)
|
||||
s_detect_callback();
|
||||
|
@ -178,7 +186,7 @@ void StopScanThread()
|
|||
}
|
||||
}
|
||||
|
||||
void Setup()
|
||||
static void Setup()
|
||||
{
|
||||
libusb_device** list;
|
||||
ssize_t cnt = libusb_get_device_list(s_libusb_context, &list);
|
||||
|
@ -307,7 +315,7 @@ static void AddGCAdapter(libusb_device* device)
|
|||
s_detected = true;
|
||||
if (s_detect_callback != nullptr)
|
||||
s_detect_callback();
|
||||
ResetRumble();
|
||||
ResetRumbleLockNeeded();
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
|
@ -328,8 +336,11 @@ void Shutdown()
|
|||
s_libusb_driver_not_supported = false;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
static void Reset()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(s_init_mutex, std::defer_lock);
|
||||
if (!lock.try_lock())
|
||||
return;
|
||||
if (!s_detected)
|
||||
return;
|
||||
|
||||
|
@ -443,10 +454,20 @@ bool UseAdapter()
|
|||
|
||||
void ResetRumble()
|
||||
{
|
||||
if (!UseAdapter())
|
||||
std::unique_lock<std::mutex> lock(s_init_mutex, std::defer_lock);
|
||||
if (!lock.try_lock())
|
||||
return;
|
||||
if (s_handle == nullptr || !s_detected)
|
||||
ResetRumbleLockNeeded();
|
||||
}
|
||||
|
||||
// Needs to be called when s_init_mutex is locked in order to avoid
|
||||
// being called while the libusb state is being reset
|
||||
static void ResetRumbleLockNeeded()
|
||||
{
|
||||
if (!UseAdapter() || (s_handle == nullptr || !s_detected))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::fill(std::begin(s_controller_rumble), std::end(s_controller_rumble), 0);
|
||||
|
||||
|
|
|
@ -19,9 +19,7 @@ enum ControllerTypes
|
|||
CONTROLLER_WIRELESS = 2
|
||||
};
|
||||
void Init();
|
||||
void Reset();
|
||||
void ResetRumble();
|
||||
void Setup();
|
||||
void Shutdown();
|
||||
void SetAdapterCallback(std::function<void(void)> func);
|
||||
void StartScanThread();
|
||||
|
|
|
@ -24,6 +24,9 @@ extern JavaVM* g_java_vm;
|
|||
|
||||
namespace GCAdapter
|
||||
{
|
||||
static void Setup();
|
||||
static void Reset();
|
||||
|
||||
// Java classes
|
||||
static jclass s_adapter_class;
|
||||
|
||||
|
@ -207,7 +210,7 @@ void Init()
|
|||
StartScanThread();
|
||||
}
|
||||
|
||||
void Setup()
|
||||
static void Setup()
|
||||
{
|
||||
s_fd = 0;
|
||||
s_detected = true;
|
||||
|
@ -220,7 +223,7 @@ void Setup()
|
|||
s_read_adapter_thread = std::thread(Read);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
static void Reset()
|
||||
{
|
||||
if (!s_detected)
|
||||
return;
|
||||
|
|
|
@ -9,9 +9,7 @@ namespace GCAdapter
|
|||
{
|
||||
|
||||
void Init() {}
|
||||
void Reset() {}
|
||||
void ResetRumble() {}
|
||||
void Setup() {}
|
||||
void Shutdown() {}
|
||||
void SetAdapterCallback(std::function<void(void)> func) {}
|
||||
void StartScanThread() {}
|
||||
|
|
Loading…
Reference in New Issue