Skip to content
Permalink
Browse files

fix SIGINT handling, add more exit codes

pass spring::EXIT_CODE_* to exit() calls
  • Loading branch information...
rtri
rtri committed Sep 24, 2019
1 parent 013f817 commit db9438c3db007a18286ecfbba60c7751adf3dcac
@@ -443,7 +443,7 @@ void CGame::Load(const std::string& mapFileName)
AddTimedJobs();

if (forcedQuit)
spring::exitCode = spring::EXIT_CODE_FORCED;
spring::exitCode = spring::EXIT_CODE_NOLOAD;

loadDone = true;
globalQuit = globalQuit | forcedQuit;
@@ -21,8 +21,9 @@
#include <libunwind.h>
#include <dlfcn.h>

#include "System/FileSystem/FileSystem.h"
#include "Game/GameVersion.h"
#include "System/FileSystem/FileSystem.h"
#include "System/SpringExitCode.h"
#include "System/Log/ILog.h"
#include "System/Log/LogSinkHandler.h"
#include "System/LogOutput.h"
@@ -662,23 +663,18 @@ static void LogStacktrace(const int logLevel, StackTrace& stacktrace)



__FORCE_ALIGN_STACK__
static void ForcedExitAfterFiveSecs() {
spring::this_thread::sleep_for(std::chrono::seconds(5));
std::exit(-1);
}

__FORCE_ALIGN_STACK__
static void ForcedExitAfterTenSecs() {
spring::this_thread::sleep_for(std::chrono::seconds(10));
#if defined(__GNUC__)
std::_Exit(-1);
#else
std::quick_exit(-1);
#endif
static void ForcedExit(int secs)
{
std::function<void()> func = [secs]() {
spring::this_thread::sleep_for(std::chrono::seconds(secs));
std::exit(spring::EXIT_CODE_KILLED);
};
spring::thread thread{func};

assert(thread.joinable());
thread.detach();
}


typedef struct sigaction sigaction_t;
typedef void (*sigact_handler_t)(int, siginfo_t*, void*);

@@ -951,9 +947,8 @@ namespace CrashHandler
event.type = SDL_QUIT;
SDL_PushEvent(&event);

// abort after 5sec
spring::thread(std::bind(&ForcedExitAfterFiveSecs));
spring::thread(std::bind(&ForcedExitAfterTenSecs));
// force an exit if no such luck
ForcedExit(5);
return;
} break;
case SIGCONT: {
@@ -11,6 +11,7 @@
#include <string>
#include <functional>

#include "System/SpringExitCode.h"
#include "System/Log/ILog.h"
#include "System/Log/LogSinkHandler.h"
#include "System/Threading/SpringThreading.h"
@@ -30,19 +31,18 @@

static void ExitSpringProcessAux(bool waitForExit, bool exitSuccess)
{
// wait 10 seconds before forcing the kill
for (unsigned int n = 0; (waitForExit && n < 10); ++n) {
spring::this_thread::sleep_for(std::chrono::seconds(1));
}
// wait a bit before forcing the kill
if (waitForExit)
spring::this_thread::sleep_for(std::chrono::seconds(5));

logSinkHandler.SetSinking(false);

#ifdef _MSC_VER
if (!exitSuccess)
TerminateProcess(GetCurrentProcess(), EXIT_FAILURE);
TerminateProcess(GetCurrentProcess(), spring::EXIT_CODE_CRASHED);
#endif

exit(EXIT_FAILURE);
exit(spring::EXIT_CODE_CRASHED);
}


@@ -413,13 +413,13 @@ void SpringApp::ParseCmdLine(int argc, char* argv[])

if (FLAGS_gen_fontconfig) {
CFontTexture::GenFontConfig();
exit(EXIT_SUCCESS);
exit(spring::EXIT_CODE_SUCCESS);
}

if (FLAGS_sync_version) {
// Note, the missing "Spring " is intentionally to make it compatible with `spring-dedicated --sync-version`
std::cout << SpringVersion::GetSync() << std::endl;
exit(EXIT_SUCCESS);
exit(spring::EXIT_CODE_SUCCESS);
}

if (FLAGS_isolation)
@@ -438,34 +438,34 @@ void SpringApp::ParseCmdLine(int argc, char* argv[])
// Interface Documentations in JSON-Format
if (FLAGS_list_config_vars) {
ConfigVariable::OutputMetaDataMap();
exit(EXIT_SUCCESS);
exit(spring::EXIT_CODE_SUCCESS);
}
if (FLAGS_list_def_tags) {
DefType::OutputTagMap();
exit(EXIT_SUCCESS);
exit(spring::EXIT_CODE_SUCCESS);
}
if (FLAGS_list_ceg_classes)
exit(CCustomExplosionGenerator::OutputProjectileClassInfo() ? EXIT_SUCCESS : EXIT_FAILURE);
exit(CCustomExplosionGenerator::OutputProjectileClassInfo() ? spring::EXIT_CODE_SUCCESS : spring::EXIT_CODE_FAILURE);

// Runtime Tests
if (FLAGS_test_creg) {
#ifdef USING_CREG
exit(creg::RuntimeTest() ? EXIT_SUCCESS : EXIT_FAILURE);
exit(creg::RuntimeTest() ? spring::EXIT_CODE_SUCCESS : spring::EXIT_CODE_FAILURE);
#else
exit(EXIT_FAILURE); //Do not fail tests
exit(spring::EXIT_CODE_SUCCESS);
#endif
}

// mutually exclusive options that cause spring to quit immediately
if (FLAGS_list_ai_interfaces) {
ConsolePrintInitialize(FLAGS_config, FLAGS_safemode);
AILibraryManager::OutputAIInterfacesInfo();
exit(EXIT_SUCCESS);
exit(spring::EXIT_CODE_SUCCESS);
}
else if (FLAGS_list_skirmish_ais) {
ConsolePrintInitialize(FLAGS_config, FLAGS_safemode);
AILibraryManager::OutputSkirmishAIInfo();
exit(EXIT_SUCCESS);
exit(spring::EXIT_CODE_SUCCESS);
}

CTextureAtlas::SetDebug(FLAGS_textureatlas);
@@ -786,7 +786,7 @@ int SpringApp::Run()
// ErrorMsgBox sets threadError if called from any non-main thread
try {
if ((gu->globalQuit = !Init() || gu->globalQuit))
spring::exitCode = spring::EXIT_CODE_FAILURE;
spring::exitCode = spring::EXIT_CODE_NOINIT;

while (!gu->globalQuit) {
Watchdog::ClearTimer(WDT_MAIN);
@@ -5,11 +5,14 @@

namespace spring {
enum {
EXIT_CODE_FAILURE = -1002, // SpringApp::Run
EXIT_CODE_CRASHED = -1003, // ErrorHandler::ExitProcess
EXIT_CODE_NOINIT = -1002, // SpringApp::Run
EXIT_CODE_DESYNC = -1001, // GameServer::CheckSync
EXIT_CODE_SUCCESS = 0,
EXIT_CODE_FAILURE = 1, // SpringApp::ParseCmdLine
EXIT_CODE_TIMEOUT = 1001, // PreGame::UpdateClientNet
EXIT_CODE_FORCED = 1002, // Game::Load
EXIT_CODE_NOLOAD = 1002, // Game::Load
EXIT_CODE_KILLED = 1003, // CrashHandler::ForcedExit
};

// only here for validation tests

0 comments on commit db9438c

Please sign in to comment.
You can’t perform that action at this time.