Merge pull request #5517 from leoetlino/more-reliable-shutdown

More reliable shutdown
This commit is contained in:
Leo Lam 2017-06-03 21:33:43 +02:00 committed by GitHub
commit 227bc3816f
2 changed files with 37 additions and 34 deletions

View File

@ -24,6 +24,7 @@
#include "Common/Logging/LogManager.h" #include "Common/Logging/LogManager.h"
#include "Common/MemoryUtil.h" #include "Common/MemoryUtil.h"
#include "Common/MsgHandler.h" #include "Common/MsgHandler.h"
#include "Common/ScopeGuard.h"
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
#include "Common/Thread.h" #include "Common/Thread.h"
#include "Common/Timer.h" #include "Common/Timer.h"
@ -453,6 +454,19 @@ static void EmuThread()
{ {
const SConfig& core_parameter = SConfig::GetInstance(); const SConfig& core_parameter = SConfig::GetInstance();
s_is_booting.Set(); s_is_booting.Set();
Common::ScopeGuard flag_guard{[] {
s_is_booting.Clear();
s_is_started = false;
s_is_stopping = false;
if (s_on_stopped_callback)
s_on_stopped_callback();
INFO_LOG(CONSOLE, "Stop\t\t---- Shutdown complete ----");
}};
// Prevent the UI from getting stuck whenever an error occurs.
Common::ScopeGuard stop_message_guard{[] { Host_Message(WM_USER_STOP); }};
Common::SetCurrentThreadName("Emuthread - Starting"); Common::SetCurrentThreadName("Emuthread - Starting");
@ -466,16 +480,23 @@ static void EmuThread()
DeclareAsCPUThread(); DeclareAsCPUThread();
Movie::Init(); Movie::Init();
Common::ScopeGuard movie_guard{Movie::Shutdown};
HW::Init(); HW::Init();
Common::ScopeGuard hw_guard{[] {
// We must set up this flag before executing HW::Shutdown()
s_hardware_initialized = false;
INFO_LOG(CONSOLE, "%s", StopMessage(false, "Shutting down HW").c_str());
HW::Shutdown();
INFO_LOG(CONSOLE, "%s", StopMessage(false, "HW shutdown").c_str());
}};
if (!g_video_backend->Initialize(s_window_handle)) if (!g_video_backend->Initialize(s_window_handle))
{ {
s_is_booting.Clear();
PanicAlert("Failed to initialize video backend!"); PanicAlert("Failed to initialize video backend!");
Host_Message(WM_USER_STOP);
return; return;
} }
Common::ScopeGuard video_guard{[] { g_video_backend->Shutdown(); }};
OSD::AddMessage("Dolphin " + g_video_backend->GetName() + " Video Backend.", 5000); OSD::AddMessage("Dolphin " + g_video_backend->GetName() + " Video Backend.", 5000);
@ -486,11 +507,7 @@ static void EmuThread()
if (!DSP::GetDSPEmulator()->Initialize(core_parameter.bWii, core_parameter.bDSPThread)) if (!DSP::GetDSPEmulator()->Initialize(core_parameter.bWii, core_parameter.bDSPThread))
{ {
s_is_booting.Clear();
HW::Shutdown();
g_video_backend->Shutdown();
PanicAlert("Failed to initialize DSP emulation!"); PanicAlert("Failed to initialize DSP emulation!");
Host_Message(WM_USER_STOP);
return; return;
} }
@ -520,7 +537,18 @@ static void EmuThread()
Wiimote::LoadConfig(); Wiimote::LoadConfig();
} }
Common::ScopeGuard controller_guard{[init_controllers] {
if (!init_controllers)
return;
Wiimote::Shutdown();
Keyboard::Shutdown();
Pad::Shutdown();
g_controller_interface.Shutdown();
}};
AudioCommon::InitSoundStream(); AudioCommon::InitSoundStream();
Common::ScopeGuard audio_guard{AudioCommon::ShutdownSoundStream};
// The hardware is initialized. // The hardware is initialized.
s_hardware_initialized = true; s_hardware_initialized = true;
@ -617,40 +645,15 @@ static void EmuThread()
if (core_parameter.bCPUThread) if (core_parameter.bCPUThread)
g_video_backend->Video_Cleanup(); g_video_backend->Video_Cleanup();
// We must set up this flag before executing HW::Shutdown()
s_hardware_initialized = false;
INFO_LOG(CONSOLE, "%s", StopMessage(false, "Shutting down HW").c_str());
HW::Shutdown();
INFO_LOG(CONSOLE, "%s", StopMessage(false, "HW shutdown").c_str());
if (init_controllers)
{
Wiimote::Shutdown();
Keyboard::Shutdown();
Pad::Shutdown();
g_controller_interface.Shutdown();
init_controllers = false;
}
g_video_backend->Shutdown();
AudioCommon::ShutdownSoundStream();
INFO_LOG(CONSOLE, "%s", StopMessage(true, "Main Emu thread stopped").c_str());
// Clear on screen messages that haven't expired // Clear on screen messages that haven't expired
OSD::ClearMessages(); OSD::ClearMessages();
BootManager::RestoreConfig(); BootManager::RestoreConfig();
INFO_LOG(CONSOLE, "Stop [Video Thread]\t\t---- Shutdown complete ----");
Movie::Shutdown();
PatchEngine::Shutdown(); PatchEngine::Shutdown();
HLE::Clear(); HLE::Clear();
// If we shut down normally, the stop message does not need to be triggered.
s_is_stopping = false; stop_message_guard.Dismiss();
if (s_on_stopped_callback)
s_on_stopped_callback();
} }
// Set or get the running state // Set or get the running state

View File

@ -810,7 +810,6 @@ void CFrame::DoStop()
// don't let this function run again until it finishes, or is aborted. // don't let this function run again until it finishes, or is aborted.
m_confirm_stop = true; m_confirm_stop = true;
m_is_game_loading = false;
if (Core::GetState() != Core::State::Uninitialized || m_render_parent != nullptr) if (Core::GetState() != Core::State::Uninitialized || m_render_parent != nullptr)
{ {
#if defined __WXGTK__ #if defined __WXGTK__
@ -911,6 +910,7 @@ bool CFrame::TriggerSTMPowerEvent()
void CFrame::OnStopped() void CFrame::OnStopped()
{ {
m_confirm_stop = false; m_confirm_stop = false;
m_is_game_loading = false;
m_tried_graceful_shutdown = false; m_tried_graceful_shutdown = false;
UninhibitScreensaver(); UninhibitScreensaver();