Merge pull request #5275 from ligfx/fixhidapithread
WiimoteReal: init and destroy ScannerBackends in same thread
This commit is contained in:
commit
24d5d89056
|
@ -535,15 +535,11 @@ void WiimoteScanner::SetScanMode(WiimoteScanMode scan_mode)
|
||||||
|
|
||||||
bool WiimoteScanner::IsReady() const
|
bool WiimoteScanner::IsReady() const
|
||||||
{
|
{
|
||||||
return std::any_of(m_scanner_backends.begin(), m_scanner_backends.end(),
|
std::lock_guard<std::mutex> lg(m_backends_mutex);
|
||||||
|
return std::any_of(m_backends.begin(), m_backends.end(),
|
||||||
[](const auto& backend) { return backend->IsReady(); });
|
[](const auto& backend) { return backend->IsReady(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiimoteScanner::AddScannerBackend(std::unique_ptr<WiimoteScannerBackend> backend)
|
|
||||||
{
|
|
||||||
m_scanner_backends.emplace_back(std::move(backend));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void CheckForDisconnectedWiimotes()
|
static void CheckForDisconnectedWiimotes()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
std::lock_guard<std::mutex> lk(g_wiimotes_mutex);
|
||||||
|
@ -558,6 +554,20 @@ void WiimoteScanner::ThreadFunc()
|
||||||
|
|
||||||
NOTICE_LOG(WIIMOTE, "Wiimote scanning thread has started.");
|
NOTICE_LOG(WIIMOTE, "Wiimote scanning thread has started.");
|
||||||
|
|
||||||
|
// Create and destroy scanner backends here to ensure all operations stay on the same thread. The
|
||||||
|
// HIDAPI backend on macOS has an error condition when IOHIDManagerCreate and IOHIDManagerClose
|
||||||
|
// are called on different threads (and so reference different CFRunLoops) which can cause an
|
||||||
|
// EXC_BAD_ACCES crash.
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lg(m_backends_mutex);
|
||||||
|
|
||||||
|
m_backends.emplace_back(std::make_unique<WiimoteScannerLinux>());
|
||||||
|
m_backends.emplace_back(std::make_unique<WiimoteScannerAndroid>());
|
||||||
|
m_backends.emplace_back(std::make_unique<WiimoteScannerWindows>());
|
||||||
|
m_backends.emplace_back(std::make_unique<WiimoteScannerDarwin>());
|
||||||
|
m_backends.emplace_back(std::make_unique<WiimoteScannerHidapi>());
|
||||||
|
}
|
||||||
|
|
||||||
while (m_scan_thread_running.IsSet())
|
while (m_scan_thread_running.IsSet())
|
||||||
{
|
{
|
||||||
m_scan_mode_changed_event.WaitFor(std::chrono::milliseconds(500));
|
m_scan_mode_changed_event.WaitFor(std::chrono::milliseconds(500));
|
||||||
|
@ -567,7 +577,7 @@ void WiimoteScanner::ThreadFunc()
|
||||||
if (m_scan_mode.load() == WiimoteScanMode::DO_NOT_SCAN)
|
if (m_scan_mode.load() == WiimoteScanMode::DO_NOT_SCAN)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (const auto& backend : m_scanner_backends)
|
for (const auto& backend : m_backends)
|
||||||
{
|
{
|
||||||
if (CalculateWantedWiimotes() != 0 || CalculateWantedBB() != 0)
|
if (CalculateWantedWiimotes() != 0 || CalculateWantedBB() != 0)
|
||||||
{
|
{
|
||||||
|
@ -593,6 +603,10 @@ void WiimoteScanner::ThreadFunc()
|
||||||
m_scan_mode.store(WiimoteScanMode::DO_NOT_SCAN);
|
m_scan_mode.store(WiimoteScanMode::DO_NOT_SCAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lg(m_backends_mutex);
|
||||||
|
m_backends.clear();
|
||||||
|
}
|
||||||
NOTICE_LOG(WIIMOTE, "Wiimote scanning thread has stopped.");
|
NOTICE_LOG(WIIMOTE, "Wiimote scanning thread has stopped.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,11 +709,6 @@ void Initialize(::Wiimote::InitializeMode init_mode)
|
||||||
if (!g_real_wiimotes_initialized)
|
if (!g_real_wiimotes_initialized)
|
||||||
{
|
{
|
||||||
s_known_ids.clear();
|
s_known_ids.clear();
|
||||||
g_wiimote_scanner.AddScannerBackend(std::make_unique<WiimoteScannerLinux>());
|
|
||||||
g_wiimote_scanner.AddScannerBackend(std::make_unique<WiimoteScannerAndroid>());
|
|
||||||
g_wiimote_scanner.AddScannerBackend(std::make_unique<WiimoteScannerWindows>());
|
|
||||||
g_wiimote_scanner.AddScannerBackend(std::make_unique<WiimoteScannerDarwin>());
|
|
||||||
g_wiimote_scanner.AddScannerBackend(std::make_unique<WiimoteScannerHidapi>());
|
|
||||||
g_wiimote_scanner.StartThread();
|
g_wiimote_scanner.StartThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,18 +138,18 @@ public:
|
||||||
void StopThread();
|
void StopThread();
|
||||||
void SetScanMode(WiimoteScanMode scan_mode);
|
void SetScanMode(WiimoteScanMode scan_mode);
|
||||||
|
|
||||||
void AddScannerBackend(std::unique_ptr<WiimoteScannerBackend> backend);
|
|
||||||
bool IsReady() const;
|
bool IsReady() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ThreadFunc();
|
void ThreadFunc();
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<WiimoteScannerBackend>> m_backends;
|
||||||
|
mutable std::mutex m_backends_mutex;
|
||||||
|
|
||||||
std::thread m_scan_thread;
|
std::thread m_scan_thread;
|
||||||
Common::Flag m_scan_thread_running;
|
Common::Flag m_scan_thread_running;
|
||||||
|
|
||||||
Common::Event m_scan_mode_changed_event;
|
Common::Event m_scan_mode_changed_event;
|
||||||
std::atomic<WiimoteScanMode> m_scan_mode{WiimoteScanMode::DO_NOT_SCAN};
|
std::atomic<WiimoteScanMode> m_scan_mode{WiimoteScanMode::DO_NOT_SCAN};
|
||||||
|
|
||||||
std::vector<std::unique_ptr<WiimoteScannerBackend>> m_scanner_backends;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::mutex g_wiimotes_mutex;
|
extern std::mutex g_wiimotes_mutex;
|
||||||
|
|
Loading…
Reference in New Issue