summaryrefslogtreecommitdiff
path: root/Source/Core/DolphinWX/Frame.cpp
diff options
context:
space:
mode:
authorLéo Lam <leo@innovatetechnologi.es>2016-07-08 16:35:03 +0200
committerLéo Lam <leo@innovatetechnologi.es>2016-07-08 23:11:27 +0200
commit0f028df6b250c91a9d345f0184c12c0865714ff6 (patch)
tree6029c4373f816f1164a279a43eef2b0c86ab65b0 /Source/Core/DolphinWX/Frame.cpp
parent3f03e2d5fe27f762f362b2a5010f778b26ed0ce6 (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.cpp55
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();
+}