diff options
| author | Léo Lam <leo@innovatetechnologi.es> | 2016-07-08 16:35:03 +0200 |
|---|---|---|
| committer | Léo Lam <leo@innovatetechnologi.es> | 2016-07-08 23:11:27 +0200 |
| commit | 0f028df6b250c91a9d345f0184c12c0865714ff6 (patch) | |
| tree | 6029c4373f816f1164a279a43eef2b0c86ab65b0 /Source/Core/DolphinWX/Frame.cpp | |
| parent | 3f03e2d5fe27f762f362b2a5010f778b26ed0ce6 (diff) | |
DolphinWX: Shut down cleanly on signal
This makes DolphinWX shut down cleanly, just like it would with
File->Exit when it receives a SIGINT, SIGTERM (Unix) or some signals
on Windows.
The default signal handler will be restored after a first shutdown
signal so a second signal will exit Dolphin forcefully.
Diffstat (limited to 'Source/Core/DolphinWX/Frame.cpp')
| -rw-r--r-- | Source/Core/DolphinWX/Frame.cpp | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/Source/Core/DolphinWX/Frame.cpp b/Source/Core/DolphinWX/Frame.cpp index b853384b22..91c159229b 100644 --- a/Source/Core/DolphinWX/Frame.cpp +++ b/Source/Core/DolphinWX/Frame.cpp @@ -6,11 +6,18 @@ #include <Cocoa/Cocoa.h> #endif +#include <atomic> #include <cstddef> #include <fstream> #include <string> #include <utility> #include <vector> +#if defined(__unix__) || defined(__unix) || defined(__APPLE__) +#include <signal.h> +#endif +#ifdef _WIN32 +#include <windows.h> +#endif #include <wx/aui/auibook.h> #include <wx/aui/framemanager.h> #include <wx/filename.h> @@ -29,6 +36,7 @@ #include "Common/CommonTypes.h" #include "Common/FileUtil.h" +#include "Common/Flag.h" #include "Common/Logging/ConsoleListener.h" #include "Common/Thread.h" @@ -353,6 +361,27 @@ bool CFrame::InitControllers() return false; } +static Common::Flag s_shutdown_signal_received; + +#ifdef _WIN32 +static BOOL WINAPI s_ctrl_handler(DWORD fdwCtrlType) +{ + switch (fdwCtrlType) + { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + case CTRL_CLOSE_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + SetConsoleCtrlHandler(s_ctrl_handler, FALSE); + s_shutdown_signal_received.Set(); + return TRUE; + default: + return FALSE; + } +} +#endif + CFrame::CFrame(wxFrame* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, bool _UseDebugger, bool _BatchMode, bool ShowLogWindow, long style) @@ -498,8 +527,25 @@ CFrame::CFrame(wxFrame* parent, wxWindowID id, const wxString& title, const wxPo InitControllers(); m_poll_hotkey_timer.SetOwner(this); - Bind(wxEVT_TIMER, &CFrame::PollHotkeys, this); + Bind(wxEVT_TIMER, &CFrame::PollHotkeys, this, m_poll_hotkey_timer.GetId()); m_poll_hotkey_timer.Start(1000 / 60, wxTIMER_CONTINUOUS); + + // Shut down cleanly on SIGINT, SIGTERM (Unix) and on various signals on Windows + m_handle_signal_timer.SetOwner(this); + Bind(wxEVT_TIMER, &CFrame::HandleSignal, this, m_handle_signal_timer.GetId()); + m_handle_signal_timer.Start(100, wxTIMER_CONTINUOUS); + +#if defined(__unix__) || defined(__unix) || defined(__APPLE__) + struct sigaction sa; + sa.sa_handler = [](int unused) { s_shutdown_signal_received.Set(); }; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESETHAND; + sigaction(SIGINT, &sa, nullptr); + sigaction(SIGTERM, &sa, nullptr); +#endif +#ifdef _WIN32 + SetConsoleCtrlHandler(s_ctrl_handler, TRUE); +#endif } // Destructor CFrame::~CFrame() @@ -1679,3 +1725,10 @@ void CFrame::HandleFrameSkipHotkeys() holdFrameStepDelayCount = 0; } } + +void CFrame::HandleSignal(wxTimerEvent& event) +{ + if (!s_shutdown_signal_received.TestAndClear()) + return; + Close(); +} |
