diff options
-rw-r--r-- | src/common/polyfill_thread.h | 36 | ||||
-rw-r--r-- | src/input_common/drivers/gc_adapter.cpp | 4 | ||||
-rw-r--r-- | src/input_common/drivers/joycon.cpp | 7 |
3 files changed, 42 insertions, 5 deletions
diff --git a/src/common/polyfill_thread.h b/src/common/polyfill_thread.h index 5a8d1ce08..b2c929d2f 100644 --- a/src/common/polyfill_thread.h +++ b/src/common/polyfill_thread.h @@ -11,6 +11,8 @@ #ifdef __cpp_lib_jthread +#include <chrono> +#include <condition_variable> #include <stop_token> #include <thread> @@ -21,11 +23,23 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred&& pred) { cv.wait(lock, token, std::move(pred)); } +template <typename Rep, typename Period> +bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) { + std::condition_variable_any cv; + std::mutex m; + + // Perform the timed wait. + std::unique_lock lk{m}; + return !cv.wait_for(lk, token, rel_time, [&] { return token.stop_requested(); }); +} + } // namespace Common #else #include <atomic> +#include <chrono> +#include <condition_variable> #include <functional> #include <list> #include <memory> @@ -318,6 +332,28 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred pred) { cv.wait(lock, [&] { return pred() || token.stop_requested(); }); } +template <typename Rep, typename Period> +bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) { + if (token.stop_requested()) { + return false; + } + + bool stop_requested = false; + std::condition_variable cv; + std::mutex m; + + std::stop_callback cb(token, [&] { + // Wake up the waiting thread. + std::unique_lock lk{m}; + stop_requested = true; + cv.notify_one(); + }); + + // Perform the timed wait. + std::unique_lock lk{m}; + return !cv.wait_for(lk, rel_time, [&] { return stop_requested; }); +} + } // namespace Common #endif diff --git a/src/input_common/drivers/gc_adapter.cpp b/src/input_common/drivers/gc_adapter.cpp index ecb3e9dc2..d09ff178b 100644 --- a/src/input_common/drivers/gc_adapter.cpp +++ b/src/input_common/drivers/gc_adapter.cpp @@ -6,6 +6,7 @@ #include "common/logging/log.h" #include "common/param_package.h" +#include "common/polyfill_thread.h" #include "common/settings_input.h" #include "common/thread.h" #include "input_common/drivers/gc_adapter.h" @@ -217,8 +218,7 @@ void GCAdapter::AdapterScanThread(std::stop_token stop_token) { Common::SetCurrentThreadName("ScanGCAdapter"); usb_adapter_handle = nullptr; pads = {}; - while (!stop_token.stop_requested() && !Setup()) { - std::this_thread::sleep_for(std::chrono::seconds(2)); + while (!Setup() && Common::StoppableTimedWait(stop_token, std::chrono::seconds{2})) { } } diff --git a/src/input_common/drivers/joycon.cpp b/src/input_common/drivers/joycon.cpp index 40cda400d..cedc94e63 100644 --- a/src/input_common/drivers/joycon.cpp +++ b/src/input_common/drivers/joycon.cpp @@ -5,6 +5,7 @@ #include "common/param_package.h" #include "common/polyfill_ranges.h" +#include "common/polyfill_thread.h" #include "common/settings.h" #include "common/thread.h" #include "input_common/drivers/joycon.h" @@ -67,7 +68,8 @@ void Joycons::Setup() { void Joycons::ScanThread(std::stop_token stop_token) { constexpr u16 nintendo_vendor_id = 0x057e; Common::SetCurrentThreadName("JoyconScanThread"); - while (!stop_token.stop_requested()) { + + do { SDL_hid_device_info* devs = SDL_hid_enumerate(nintendo_vendor_id, 0x0); SDL_hid_device_info* cur_dev = devs; @@ -81,8 +83,7 @@ void Joycons::ScanThread(std::stop_token stop_token) { } SDL_hid_free_enumeration(devs); - std::this_thread::sleep_for(std::chrono::seconds(5)); - } + } while (Common::StoppableTimedWait(stop_token, std::chrono::seconds{5})); } bool Joycons::IsDeviceNew(SDL_hid_device_info* device_info) const { |