mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
Use a single libusb context
libusb on Windows is limited to only a single context. Trying to open more than one can cause device enumerations to fail randomly. libusb is thread-safe and we don't use the manual polling support (with `poll()`) so this should be safe.
This commit is contained in:
46
Source/Core/Common/LibusbContext.cpp
Normal file
46
Source/Core/Common/LibusbContext.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <libusb.h>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include "Common/LibusbContext.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
|
||||
namespace LibusbContext
|
||||
{
|
||||
static std::shared_ptr<libusb_context> s_libusb_context;
|
||||
static std::once_flag s_context_initialized;
|
||||
|
||||
static libusb_context* Create()
|
||||
{
|
||||
libusb_context* context;
|
||||
const int ret = libusb_init(&context);
|
||||
if (ret < LIBUSB_SUCCESS)
|
||||
{
|
||||
bool is_windows = false;
|
||||
#ifdef _WIN32
|
||||
is_windows = true;
|
||||
#endif
|
||||
if (is_windows && ret == LIBUSB_ERROR_NOT_FOUND)
|
||||
PanicAlertT("Failed to initialize libusb because usbdk is not installed.");
|
||||
else
|
||||
PanicAlertT("Failed to initialize libusb: %s", libusb_error_name(ret));
|
||||
return nullptr;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
std::shared_ptr<libusb_context> Get()
|
||||
{
|
||||
std::call_once(s_context_initialized, []() {
|
||||
s_libusb_context.reset(Create(), [](auto* context) {
|
||||
if (context != nullptr)
|
||||
libusb_exit(context);
|
||||
});
|
||||
});
|
||||
return s_libusb_context;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user