diff --git a/Source/Core/Common/Src/Thread.cpp b/Source/Core/Common/Src/Thread.cpp index 7057a137ac..57196c837b 100644 --- a/Source/Core/Common/Src/Thread.cpp +++ b/Source/Core/Common/Src/Thread.cpp @@ -91,7 +91,7 @@ void Thread::WaitForDeath() { if (m_hThread) { - WaitForSingleObject(m_hThread, INFINITE); + WaitForSingleObject(m_hThread, THREAD_WAIT_TIMEOUT); CloseHandle(m_hThread); m_hThread = NULL; } @@ -140,7 +140,7 @@ void Event::Set() void Event::Wait() { - WaitForSingleObject(m_hEvent, INFINITE); + WaitForSingleObject(m_hEvent, THREAD_WAIT_TIMEOUT); } inline HRESULT MsgWaitForSingleObject(HANDLE handle, DWORD timeout) @@ -168,7 +168,7 @@ void Event::MsgWait() // Wait for any message sent or posted to this queue // or for one of the passed handles be set to signaled. - result = MsgWaitForSingleObject(m_hEvent, INFINITE); + result = MsgWaitForSingleObject(m_hEvent, THREAD_WAIT_TIMEOUT); // The result tells us the type of event we have. if (result == (WAIT_OBJECT_0 + 1)) diff --git a/Source/Core/Common/Src/Thread.h b/Source/Core/Common/Src/Thread.h index b2d5274196..722cdf22f7 100644 --- a/Source/Core/Common/Src/Thread.h +++ b/Source/Core/Common/Src/Thread.h @@ -81,6 +81,7 @@ private: #ifdef _WIN32 HANDLE m_hThread; DWORD m_threadId; + static const int THREAD_WAIT_TIMEOUT = 5000; #else pthread_t thread_id; #endif @@ -121,6 +122,12 @@ public: private: #ifdef _WIN32 HANDLE m_hEvent; + /* If we have waited more than five seconds we can be pretty sure that the thread is deadlocked. + So then we can just as well continue and hope for the best. I could try several times that + this works after a five second timeout (with works meaning that the game stopped and I could + start another game without any noticable problems). But several times it failed to, and ended + with a crash. But it's better than an infinite deadlock. */ + static const int THREAD_WAIT_TIMEOUT = 5000; // INFINITE or 5000 for example #else bool is_set_; pthread_cond_t event_; diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index daff3af44f..b468951873 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -522,8 +522,14 @@ void CFrame::DoStop() Core::Stop(); /* This is needed together with the option to not "delete g_EmuThread" in Core.cpp, because then - we have to wait a moment before GetState() == CORE_UNINITIALIZED so that UpdateGUI() works */ - #ifdef SETUP_AVOID_CHILD_WINDOW_RENDERING_HANG + we have to wait a moment before GetState() == CORE_UNINITIALIZED so that UpdateGUI() works. + It's also needed when a WaitForSingleObject() has timed out so that the ShutDown() process + has continued without all threads having come to a rest. It's not compatible with the + SETUP_TIMER_WAITING option (because the Stop returns before it's finished). + + Without this we just see the gray CPanel background because the ISO list will not be displayed. + */ + #ifndef SETUP_TIMER_WAITING if (bRenderToMain) while(Core::GetState() != Core::CORE_UNINITIALIZED) Sleep(10); #endif