From 1c78c18997cf658e7b5f89158b6fe1de8e5c292d Mon Sep 17 00:00:00 2001 From: J Reece Wilson Date: Thu, 7 Apr 2022 06:22:50 +0100 Subject: [PATCH] [+] Exit::CancelExit() [*] Treat SIGTERM the same as SIGINT. SIGINT is somewhat of an arachic signal meaning, "hey dumb unix app, fuck the process group, start reading from stdin to listen to the user." Nowadays, this doesn't mean anything other than "hey, a human asked us to terminate from a TTY" - basically the same as SIGTERM, except SIGTERM is more likely to be a scheduled or otherwise expected shutdown event. --- Include/Aurora/Exit/Exit.hpp | 7 +++++++ Source/Debug/ExceptionWatcher.Win32.cpp | 2 +- Source/Exit/Exit.Unix.cpp | 16 +++++++++++++--- Source/Exit/Exit.cpp | 23 ++++++++++++++++++++++- Source/Exit/Exit.hpp | 2 ++ 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/Include/Aurora/Exit/Exit.hpp b/Include/Aurora/Exit/Exit.hpp index d4fd9918..b40a23c1 100644 --- a/Include/Aurora/Exit/Exit.hpp +++ b/Include/Aurora/Exit/Exit.hpp @@ -33,4 +33,11 @@ namespace Aurora::Exit * @return */ AUKN_SYM bool IsAppRunning(); + + + /** + * @brief Used from within eSigTerminate callbacks to prevent automatic shutdown of the application + * @return + */ + AUKN_SYM void CancelExit(); } \ No newline at end of file diff --git a/Source/Debug/ExceptionWatcher.Win32.cpp b/Source/Debug/ExceptionWatcher.Win32.cpp index 66700473..c31eda52 100644 --- a/Source/Debug/ExceptionWatcher.Win32.cpp +++ b/Source/Debug/ExceptionWatcher.Win32.cpp @@ -111,7 +111,7 @@ namespace Aurora::Debug if (ExceptionInfo->ExceptionRecord->ExceptionCode == DBG_CONTROL_C) { Exit::PostLevel(AuThreads::GetThread(), Exit::ETriggerLevel::eSigTerminate); - return EXCEPTION_CONTINUE_SEARCH; + return Exit::gHasCanceled ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH; } if (ExceptionInfo->ExceptionRecord->ExceptionCode < STATUS_GUARD_PAGE_VIOLATION) diff --git a/Source/Exit/Exit.Unix.cpp b/Source/Exit/Exit.Unix.cpp index e5170c32..be5280ea 100644 --- a/Source/Exit/Exit.Unix.cpp +++ b/Source/Exit/Exit.Unix.cpp @@ -18,9 +18,17 @@ namespace Aurora::Exit static void HandleSigTerminate(int sig) { - Grug::Arrow arrow; - Grug::HurlArrow(&arrow, SendExitSignal, {}); - Grug::ArrowWait(&arrow); + static Grug::Arrow arrow; + + if (sig == SIGINT) + { + Grug::HurlArrow(&arrow, {}, SendExitSignal); + } + else + { + Grug::HurlArrow(&arrow, SendExitSignal, {}); + Grug::ArrowWait(&arrow); + } } void InitUnix() @@ -33,6 +41,7 @@ namespace Aurora::Exit sigemptyset(&action.sa_mask); sigaction(SIGINT, &action, nullptr); + sigaction(SIGTERM, &action, nullptr); } void DeinitUnix() @@ -45,5 +54,6 @@ namespace Aurora::Exit sigemptyset(&action.sa_mask); sigaction(SIGINT, &action, nullptr); + sigaction(SIGTERM, &action, nullptr); } } \ No newline at end of file diff --git a/Source/Exit/Exit.cpp b/Source/Exit/Exit.cpp index 48cc3c77..e1fb0c7a 100644 --- a/Source/Exit/Exit.cpp +++ b/Source/Exit/Exit.cpp @@ -41,6 +41,8 @@ namespace Aurora::Exit void PostLevel(AuThreads::IAuroraThread *thread, ETriggerLevel level) { + bool bOldTerminatingValue; + { AU_LOCK_GUARD(gMutex); @@ -54,6 +56,7 @@ namespace Aurora::Exit } // + bOldTerminatingValue = gIsAppRunning; if (isTerminate || level == ETriggerLevel::eSigTerminate) { gIsAppRunning = false; @@ -68,6 +71,10 @@ namespace Aurora::Exit return; } } + + // HACK: + gHasCanceled = false; + // Dispatch DispatchHandlersForThread(thread, level); @@ -97,7 +104,15 @@ namespace Aurora::Exit // Force exit after calling the subscribers, should the even level be eSigTerminate if (level == ETriggerLevel::eSigTerminate) { - Process::Exit(0); + // HACK: + if (gHasCanceled) + { + gIsAppRunning = bOldTerminatingValue; + } + else + { + Process::Exit(0); + } } } @@ -123,6 +138,12 @@ namespace Aurora::Exit return gIsAppRunning; } + AUKN_SYM void CancelExit() + { + // HACK: + gHasCanceled = true; + } + void InitExit() { gMutex = AuThreadPrimitives::MutexUnique(); diff --git a/Source/Exit/Exit.hpp b/Source/Exit/Exit.hpp index c8ea3e0f..6175d84c 100644 --- a/Source/Exit/Exit.hpp +++ b/Source/Exit/Exit.hpp @@ -9,6 +9,8 @@ namespace Aurora::Exit { + inline bool gHasCanceled {false}; + void PostLevel(AuThreads::IAuroraThread *thread, ETriggerLevel level); void InitExit();