Merge pull request #8218 from leoetlino/context

Use separate libusb contexts to avoid thread safety issues
This commit is contained in:
Léo Lam
2019-07-11 17:28:19 +02:00
committed by GitHub
8 changed files with 18 additions and 30 deletions

View File

@@ -28,7 +28,6 @@
#include "Core/Core.h"
#include "Core/HW/Memmap.h"
#include "Core/IOS/Device.h"
#include "Core/LibusbUtils.h"
#include "VideoCommon/OnScreenDisplay.h"
namespace IOS::HLE::Device
@@ -75,11 +74,10 @@ BluetoothReal::~BluetoothReal()
IPCCommandResult BluetoothReal::Open(const OpenRequest& request)
{
auto& context = LibusbUtils::GetContext();
if (!context.IsValid())
if (!m_context.IsValid())
return GetDefaultReply(IPC_EACCES);
context.GetDeviceList([this](libusb_device* device) {
m_context.GetDeviceList([this](libusb_device* device) {
libusb_device_descriptor device_descriptor;
libusb_get_device_descriptor(device, &device_descriptor);
auto config_descriptor = LibusbUtils::MakeConfigDescriptor(device);
@@ -599,8 +597,7 @@ void BluetoothReal::HandleCtrlTransfer(libusb_transfer* tr)
}
const auto& command = m_current_transfers.at(tr).command;
command->FillBuffer(libusb_control_transfer_get_data(tr), tr->actual_length);
m_ios.EnqueueIPCReply(command->ios_request, tr->actual_length, 0,
CoreTiming::FromThread::NON_CPU);
m_ios.EnqueueIPCReply(command->ios_request, tr->actual_length, 0, CoreTiming::FromThread::ANY);
m_current_transfers.erase(tr);
}
@@ -648,8 +645,7 @@ void BluetoothReal::HandleBulkOrIntrTransfer(libusb_transfer* tr)
const auto& command = m_current_transfers.at(tr).command;
command->FillBuffer(tr->buffer, tr->actual_length);
m_ios.EnqueueIPCReply(command->ios_request, tr->actual_length, 0,
CoreTiming::FromThread::NON_CPU);
m_ios.EnqueueIPCReply(command->ios_request, tr->actual_length, 0, CoreTiming::FromThread::ANY);
m_current_transfers.erase(tr);
}
} // namespace IOS::HLE::Device

View File

@@ -19,6 +19,7 @@
#include "Core/IOS/USB/Bluetooth/BTBase.h"
#include "Core/IOS/USB/Bluetooth/hci.h"
#include "Core/IOS/USB/USBV0.h"
#include "Core/LibusbUtils.h"
class PointerWrap;
struct libusb_device;
@@ -70,6 +71,7 @@ private:
std::atomic<SyncButtonState> m_sync_button_state{SyncButtonState::Unpressed};
Common::Timer m_sync_button_held_timer;
LibusbUtils::Context m_context;
libusb_device* m_device = nullptr;
libusb_device_handle* m_handle = nullptr;

View File

@@ -24,7 +24,6 @@
#include "Core/Core.h"
#include "Core/IOS/USB/Common.h"
#include "Core/IOS/USB/LibusbDevice.h"
#include "Core/LibusbUtils.h"
namespace IOS::HLE::Device
{
@@ -121,10 +120,9 @@ bool USBHost::AddNewDevices(std::set<u64>& new_devices, DeviceChangeHooks& hooks
if (SConfig::GetInstance().m_usb_passthrough_devices.empty())
return true;
auto& context = LibusbUtils::GetContext();
if (context.IsValid())
if (m_context.IsValid())
{
context.GetDeviceList([&](libusb_device* device) {
m_context.GetDeviceList([&](libusb_device* device) {
libusb_device_descriptor descriptor;
libusb_get_device_descriptor(device, &descriptor);
const std::pair<u16, u16> vid_pid = {descriptor.idVendor, descriptor.idProduct};

View File

@@ -20,6 +20,7 @@
#include "Core/IOS/Device.h"
#include "Core/IOS/IOS.h"
#include "Core/IOS/USB/Common.h"
#include "Core/LibusbUtils.h"
class PointerWrap;
@@ -71,5 +72,6 @@ private:
std::thread m_scan_thread;
Common::Event m_first_scan_complete_event;
bool m_has_initialised = false;
LibusbUtils::Context m_context;
};
} // namespace IOS::HLE::Device

View File

@@ -109,12 +109,6 @@ bool Context::GetDeviceList(GetDeviceListCallback callback)
return m_impl->GetDeviceList(std::move(callback));
}
Context& GetContext()
{
static Context s_context;
return s_context;
}
ConfigDescriptor MakeConfigDescriptor(libusb_device* device, u8 config_num)
{
#if defined(__LIBUSB__)

View File

@@ -38,11 +38,6 @@ private:
std::unique_ptr<Impl> m_impl;
};
// Use this to get a libusb context. Do *not* use any other context
// because some libusb backends such as UsbDk only work properly with a single context.
// Additionally, device lists must be retrieved using GetDeviceList for thread safety reasons.
Context& GetContext();
using ConfigDescriptor = UniquePtr<libusb_config_descriptor>;
ConfigDescriptor MakeConfigDescriptor(libusb_device* device, u8 config_num = 0);
} // namespace LibusbUtils