Merge pull request #9839 from OatmealDome/bluetooth-scanning

WiimoteScannerDarwin: fix hang on quit and clean up
This commit is contained in:
JMC47 2021-06-29 21:07:47 -04:00 committed by GitHub
commit 6a46d35c73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 56 additions and 29 deletions

View File

@ -48,6 +48,7 @@ public:
bool IsReady() const override { return true; } bool IsReady() const override { return true; }
void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override; void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override;
void Update() override {} void Update() override {}
void RequestStopSearching() override {}
}; };
} // namespace WiimoteReal } // namespace WiimoteReal

View File

@ -16,5 +16,6 @@ public:
bool IsReady() const override { return false; } bool IsReady() const override { return false; }
void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override {} void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override {}
void Update() override {} void Update() override {}
void RequestStopSearching() override {}
}; };
} // namespace WiimoteReal } // namespace WiimoteReal

View File

@ -46,7 +46,8 @@ public:
~WiimoteScannerLinux() override; ~WiimoteScannerLinux() override;
bool IsReady() const override; bool IsReady() const override;
void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override; void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override;
void Update() override {} // not needed on Linux void Update() override {} // not needed on Linux
void RequestStopSearching() override {} // not needed on Linux
private: private:
int m_device_id; int m_device_id;
int m_device_sock; int m_device_sock;

View File

@ -52,6 +52,7 @@ public:
bool IsReady() const override; bool IsReady() const override;
void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override; void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override;
void Update() override; void Update() override;
void RequestStopSearching() override {}
}; };
} // namespace WiimoteReal } // namespace WiimoteReal

View File

@ -7,18 +7,28 @@
#ifdef __APPLE__ #ifdef __APPLE__
#include "Core/HW/WiimoteReal/WiimoteReal.h" #include "Core/HW/WiimoteReal/WiimoteReal.h"
#ifdef __OBJC__
#import <IOBluetooth/IOBluetooth.h>
#else
// IOBluetooth's types won't be defined in pure C++ mode.
typedef void IOBluetoothHostController;
#endif
namespace WiimoteReal namespace WiimoteReal
{ {
class WiimoteScannerDarwin final : public WiimoteScannerBackend class WiimoteScannerDarwin final : public WiimoteScannerBackend
{ {
public: public:
WiimoteScannerDarwin() = default; WiimoteScannerDarwin();
~WiimoteScannerDarwin() override; ~WiimoteScannerDarwin() override;
bool IsReady() const override; bool IsReady() const override;
void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override; void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override;
void Update() override {} // not needed void Update() override {} // not needed
void RequestStopSearching() override { m_stop_scanning = true; }
private: private:
bool stopScanning = false; IOBluetoothHostController* m_host_controller;
bool m_stop_scanning = false;
}; };
} // namespace WiimoteReal } // namespace WiimoteReal

View File

@ -21,28 +21,41 @@
namespace WiimoteReal namespace WiimoteReal
{ {
WiimoteScannerDarwin::WiimoteScannerDarwin()
{
m_host_controller = [IOBluetoothHostController defaultController];
if (![m_host_controller addressAsString])
{
WARN_LOG_FMT(WIIMOTE, "No Bluetooth host controller");
[m_host_controller release];
m_host_controller = nil;
return;
}
[m_host_controller retain];
}
WiimoteScannerDarwin::~WiimoteScannerDarwin() WiimoteScannerDarwin::~WiimoteScannerDarwin()
{ {
stopScanning = true; [m_host_controller release];
m_host_controller = nil;
m_stop_scanning = true;
} }
void WiimoteScannerDarwin::FindWiimotes(std::vector<Wiimote*>& found_wiimotes, void WiimoteScannerDarwin::FindWiimotes(std::vector<Wiimote*>& found_wiimotes,
Wiimote*& found_board) Wiimote*& found_board)
{ {
// TODO: find the device in the constructor and save it for later if (!m_host_controller)
IOBluetoothHostController* bth;
IOBluetoothDeviceInquiry* bti;
found_board = nullptr;
bth = [[IOBluetoothHostController alloc] init];
bool btFailed = [bth addressAsString] == nil;
if (btFailed)
{ {
WARN_LOG_FMT(WIIMOTE, "No Bluetooth host controller");
[bth release];
return; return;
} }
IOBluetoothDeviceInquiry* bti;
found_board = nullptr;
SearchBT* sbt = [[SearchBT alloc] init]; SearchBT* sbt = [[SearchBT alloc] init];
sbt->maxDevices = 32; sbt->maxDevices = 32;
bti = [[IOBluetoothDeviceInquiry alloc] init]; bti = [[IOBluetoothDeviceInquiry alloc] init];
@ -52,15 +65,15 @@ void WiimoteScannerDarwin::FindWiimotes(std::vector<Wiimote*>& found_wiimotes,
if ([bti start] != kIOReturnSuccess) if ([bti start] != kIOReturnSuccess)
{ {
ERROR_LOG_FMT(WIIMOTE, "Unable to do Bluetooth discovery"); ERROR_LOG_FMT(WIIMOTE, "Unable to do Bluetooth discovery");
[bth release];
[sbt release]; [sbt release];
btFailed = true;
return;
} }
do do
{ {
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false); CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
} while (!sbt->done && !stopScanning); } while (!sbt->done && !m_stop_scanning);
int found_devices = [[bti foundDevices] count]; int found_devices = [[bti foundDevices] count];
@ -86,15 +99,13 @@ void WiimoteScannerDarwin::FindWiimotes(std::vector<Wiimote*>& found_wiimotes,
} }
} }
[bth release];
[bti release]; [bti release];
[sbt release]; [sbt release];
} }
bool WiimoteScannerDarwin::IsReady() const bool WiimoteScannerDarwin::IsReady() const
{ {
// TODO: only return true when a BT device is present return m_host_controller != nil;
return true;
} }
WiimoteDarwin::WiimoteDarwin(IOBluetoothDevice* device) : m_btd(device) WiimoteDarwin::WiimoteDarwin(IOBluetoothDevice* device) : m_btd(device)

View File

@ -4,13 +4,6 @@
#pragma once #pragma once
// Work around an Apple bug: for some reason, IOBluetooth.h errors on
// inclusion in Mavericks, but only in Objective-C++ C++11 mode. I filed
// this as <rdar://15312520>; in the meantime...
#import <Foundation/Foundation.h>
#undef NS_ENUM_AVAILABLE
#define NS_ENUM_AVAILABLE(...)
// end hack
#import <IOBluetooth/IOBluetooth.h> #import <IOBluetooth/IOBluetooth.h>
#include <IOKit/pwr_mgt/IOPMLib.h> #include <IOKit/pwr_mgt/IOPMLib.h>

View File

@ -38,7 +38,8 @@ public:
~WiimoteScannerHidapi(); ~WiimoteScannerHidapi();
bool IsReady() const override; bool IsReady() const override;
void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override; void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) override;
void Update() override {} // not needed for hidapi void Update() override {} // not needed for hidapi
void RequestStopSearching() override {} // not needed for hidapi
}; };
} // namespace WiimoteReal } // namespace WiimoteReal

View File

@ -545,6 +545,12 @@ void WiimoteScanner::StopThread()
if (m_scan_thread_running.TestAndClear()) if (m_scan_thread_running.TestAndClear())
{ {
SetScanMode(WiimoteScanMode::DO_NOT_SCAN); SetScanMode(WiimoteScanMode::DO_NOT_SCAN);
for (const auto& backend : m_backends)
{
backend->RequestStopSearching();
}
m_scan_thread.join(); m_scan_thread.join();
} }
} }

View File

@ -1,4 +1,4 @@
// Copyright 2008 Dolphin Emulator Project // Copyright 2008 Dolphin Emulator Project
// Licensed under GPLv2+ // Licensed under GPLv2+
// Refer to the license.txt file included. // Refer to the license.txt file included.
@ -155,6 +155,8 @@ public:
virtual void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) = 0; virtual void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&) = 0;
// function called when not looking for more Wiimotes // function called when not looking for more Wiimotes
virtual void Update() = 0; virtual void Update() = 0;
// requests the backend to stop scanning if FindWiimotes is blocking
virtual void RequestStopSearching() = 0;
}; };
enum class WiimoteScanMode enum class WiimoteScanMode