From ed8f293b4f4c340dc342e54532fcdd953056efab Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Thu, 22 Jun 2017 05:42:14 -0700 Subject: [PATCH] Change "blocking" BlockingLoop::Stop to give up and die after a timeout. This fixes the global-static fifo object causing infinite hangs in some cases. Notably, failure to initialize a graphics backend would result in BlockingLoop::Prepare being called but never executing Run(), leaving the object in a bad state. --- Source/Core/Common/BlockingLoop.h | 23 ++++++++++++++++++++--- Source/Core/VideoCommon/Fifo.cpp | 2 +- 2 files changed, 21 insertions(+), 4 deletions(-) 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)