From 4315a113935902bbbb82047e3f43695b4d76fff2 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 17 Jun 2015 15:38:00 +0100 Subject: Fixed and improved restarting Restarts are now an actual, close-as-possible to application exit+reopen. --- src/main.cpp | 65 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 33 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index d0a5eb203..bc2439616 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,9 +22,6 @@ /** If something has told the server to stop; checked periodically in cRoot */ bool cRoot::m_TerminateEventRaised = false; -/** Set to true when the server terminates, so our CTRL handler can then tell the OS to close the console. */ -static bool g_ServerTerminated = false; - /** If set to true, the protocols will log each player's incoming (C->S) communication to a per-connection logfile */ bool g_ShouldLogCommIn; @@ -72,7 +69,7 @@ Synchronize this with Server.cpp to enable the "dumpmem" console command. */ void NonCtrlHandler(int a_Signal) { LOGD("Terminate event raised from std::signal"); - cRoot::m_TerminateEventRaised = true; + cRoot::Get()->QueueExecuteConsoleCommand("stop"); switch (a_Signal) { @@ -189,13 +186,11 @@ LONG WINAPI LastChanceExceptionFilter(__in struct _EXCEPTION_POINTERS * a_Except // Handle CTRL events in windows, including console window close BOOL CtrlHandler(DWORD fdwCtrlType) { - cRoot::m_TerminateEventRaised = true; + cRoot::Get()->QueueExecuteConsoleCommand("stop"); LOGD("Terminate event raised from the Windows CtrlHandler"); - while (!g_ServerTerminated) - { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Delay as much as possible to try to get the server to shut down cleanly - } + std::this_thread::sleep_for(std::chrono::seconds(10)); // Delay as much as possible to try to get the server to shut down cleanly - 10 seconds given by Windows + // Returning from main() automatically aborts this handler thread return TRUE; } @@ -206,29 +201,22 @@ BOOL CtrlHandler(DWORD fdwCtrlType) //////////////////////////////////////////////////////////////////////////////// -// universalMain - Main startup logic for both standard running and as a service +// UniversalMain - Main startup logic for both standard running and as a service -void universalMain(std::unique_ptr overridesRepo) +void UniversalMain(std::unique_ptr a_OverridesRepo) { - #ifdef _WIN32 - if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE)) - { - LOGERROR("Could not install the Windows CTRL handler!"); - } - #endif - // Initialize logging subsystem: cLogger::InitiateMultithreading(); // Initialize LibEvent: - cNetworkSingleton::Get(); + cNetworkSingleton::Get().Initialise(); #if !defined(ANDROID_NDK) try #endif { cRoot Root; - Root.Start(std::move(overridesRepo)); + Root.Start(std::move(a_OverridesRepo)); } #if !defined(ANDROID_NDK) catch (std::exception & e) @@ -241,8 +229,6 @@ void universalMain(std::unique_ptr overridesRepo) } #endif - g_ServerTerminated = true; - // Shutdown all of LibEvent: cNetworkSingleton::Get().Terminate(); } @@ -259,8 +245,11 @@ DWORD WINAPI serviceWorkerThread(LPVOID lpParam) { UNREFERENCED_PARAMETER(lpParam); - // Do the normal startup - universalMain(cpp14::make_unique()); + while (!cRoot::m_TerminateEventRaised) + { + // Do the normal startup + UniversalMain(cpp14::make_unique()); + } return ERROR_SUCCESS; } @@ -274,8 +263,7 @@ DWORD WINAPI serviceWorkerThread(LPVOID lpParam) void serviceSetState(DWORD acceptedControls, DWORD newState, DWORD exitCode) { - SERVICE_STATUS serviceStatus; - ZeroMemory(&serviceStatus, sizeof(SERVICE_STATUS)); + SERVICE_STATUS serviceStatus = {}; serviceStatus.dwCheckPoint = 0; serviceStatus.dwControlsAccepted = acceptedControls; serviceStatus.dwCurrentState = newState; @@ -302,11 +290,10 @@ void WINAPI serviceCtrlHandler(DWORD CtrlCode) { case SERVICE_CONTROL_STOP: { - cRoot::m_ShouldStop = true; + cRoot::Get()->QueueExecuteConsoleCommand("stop"); serviceSetState(0, SERVICE_STOP_PENDING, 0); break; } - default: { break; @@ -365,7 +352,7 @@ void WINAPI serviceMain(DWORD argc, TCHAR *argv[]) -std::unique_ptr parseArguments(int argc, char **argv) +std::unique_ptr ParseArguments(int argc, char **argv) { try { @@ -484,7 +471,13 @@ int main(int argc, char **argv) #endif // SIGABRT_COMPAT #endif - auto argsRepo = parseArguments(argc, argv); + + #ifdef _WIN32 + if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE)) + { + LOGERROR("Could not install the Windows CTRL handler!"); + } + #endif // Attempt to run as a service if (cRoot::m_RunAsService) @@ -522,13 +515,19 @@ int main(int argc, char **argv) close(STDOUT_FILENO); close(STDERR_FILENO); - universalMain(std::move(argsRepo)); + while (!cRoot::m_TerminateEventRaised) + { + UniversalMain(std::move(ParseArguments(argc, argv))); + } #endif } else { - // Not running as a service, do normal startup - universalMain(std::move(argsRepo)); + while (!cRoot::m_TerminateEventRaised) + { + // Not running as a service, do normal startup + UniversalMain(std::move(ParseArguments(argc, argv))); + } } #if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER) -- cgit v1.2.3