diff --git a/Source/Core/Common/BlockingLoop.h b/Source/Core/Common/BlockingLoop.h index a1ebe7d708..f8e9f85164 100644 --- a/Source/Core/Common/BlockingLoop.h +++ b/Source/Core/Common/BlockingLoop.h @@ -22,8 +22,15 @@ namespace Common class BlockingLoop { public: + enum StopMode + { + kNonBlock, + kBlock, + kBlockAndGiveUp, + }; + BlockingLoop() { m_stopped.Set(); } - ~BlockingLoop() { Stop(); } + ~BlockingLoop() { Stop(kBlockAndGiveUp); } // Triggers to rerun the payload of the Run() function at least once again. // This function will never block and is designed to finish as fast as possible. void Wakeup() @@ -192,7 +199,7 @@ public: // Quits the main loop. // By default, it will wait until the main loop quits. // Be careful to not use the blocking way within the payload of the Run() method. - void Stop(bool block = true) + void Stop(StopMode mode = kBlock) { if (m_stopped.IsSet()) return; @@ -202,8 +209,18 @@ public: // We have to interrupt the sleeping call to let the worker shut down soon. Wakeup(); - if (block) + switch (mode) + { + case kBlock: Wait(); + break; + case kBlockAndGiveUp: + WaitYield(std::chrono::milliseconds(100), [&] { + // If timed out, assume no one will come along to call Run, so force a break + m_stopped.Set(); + }); + break; + } } bool IsRunning() const { return !m_stopped.IsSet() && !m_shutdown.IsSet(); } diff --git a/Source/Core/VideoCommon/Fifo.cpp b/Source/Core/VideoCommon/Fifo.cpp index cedbea5432..15a1853ee7 100644 --- a/Source/Core/VideoCommon/Fifo.cpp +++ b/Source/Core/VideoCommon/Fifo.cpp @@ -144,7 +144,7 @@ void ExitGpuLoop() // Terminate GPU thread loop s_emu_running_state.Set(); - s_gpu_mainloop.Stop(false); + s_gpu_mainloop.Stop(s_gpu_mainloop.kNonBlock); } void EmulatorState(bool running)