mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -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:
@ -34,6 +34,11 @@ set(SRCS Analytics.cpp
|
||||
Crypto/ec.cpp
|
||||
Logging/LogManager.cpp)
|
||||
|
||||
if(LIBUSB_FOUND)
|
||||
set(LIBS ${LIBS} ${LIBUSB_LIBRARIES})
|
||||
set(SRCS ${SRCS} LibusbContext.cpp)
|
||||
endif(LIBUSB_FOUND)
|
||||
|
||||
if(ANDROID)
|
||||
set(SRCS ${SRCS}
|
||||
Logging/ConsoleListenerDroid.cpp)
|
||||
|
@ -113,6 +113,7 @@
|
||||
<ClInclude Include="Hash.h" />
|
||||
<ClInclude Include="IniFile.h" />
|
||||
<ClInclude Include="JitRegister.h" />
|
||||
<ClInclude Include="LibusbContext.h" />
|
||||
<ClInclude Include="LinearDiskCache.h" />
|
||||
<ClInclude Include="MathUtil.h" />
|
||||
<ClInclude Include="MD5.h" />
|
||||
@ -159,6 +160,9 @@
|
||||
<ClCompile Include="Hash.cpp" />
|
||||
<ClCompile Include="IniFile.cpp" />
|
||||
<ClCompile Include="JitRegister.cpp" />
|
||||
<ClCompile Include="LibusbContext.cpp">
|
||||
<DisableSpecificWarnings>4200;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Logging\ConsoleListenerWin.cpp" />
|
||||
<ClCompile Include="MathUtil.cpp" />
|
||||
<ClCompile Include="MD5.cpp" />
|
||||
|
@ -45,6 +45,7 @@
|
||||
<ClInclude Include="FPURoundMode.h" />
|
||||
<ClInclude Include="Hash.h" />
|
||||
<ClInclude Include="IniFile.h" />
|
||||
<ClInclude Include="LibusbContext.h" />
|
||||
<ClInclude Include="LinearDiskCache.h" />
|
||||
<ClInclude Include="MathUtil.h" />
|
||||
<ClInclude Include="MemArena.h" />
|
||||
@ -236,6 +237,7 @@
|
||||
<ClCompile Include="FileUtil.cpp" />
|
||||
<ClCompile Include="Hash.cpp" />
|
||||
<ClCompile Include="IniFile.cpp" />
|
||||
<ClCompile Include="LibusbContext.cpp" />
|
||||
<ClCompile Include="MathUtil.cpp" />
|
||||
<ClCompile Include="MemArena.cpp" />
|
||||
<ClCompile Include="MemoryUtil.cpp" />
|
||||
|
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;
|
||||
}
|
||||
}
|
15
Source/Core/Common/LibusbContext.h
Normal file
15
Source/Core/Common/LibusbContext.h
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <memory>
|
||||
|
||||
struct libusb_context;
|
||||
|
||||
namespace LibusbContext
|
||||
{
|
||||
// libusb on Windows is limited to only a single context. Trying to open more
|
||||
// than one can cause issues with device enumerations.
|
||||
// libusb is thread-safe so this context can be safely used from different threads.
|
||||
std::shared_ptr<libusb_context> Get();
|
||||
}
|
Reference in New Issue
Block a user