Fixed and improved restarting
Restarts are now an actual, close-as-possible to application exit+reopen.
This commit is contained in:
65
src/main.cpp
65
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<cSettingsRepositoryInterface> overridesRepo)
|
||||
void UniversalMain(std::unique_ptr<cSettingsRepositoryInterface> 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<cSettingsRepositoryInterface> 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<cMemorySettingsRepository>());
|
||||
while (!cRoot::m_TerminateEventRaised)
|
||||
{
|
||||
// Do the normal startup
|
||||
UniversalMain(cpp14::make_unique<cMemorySettingsRepository>());
|
||||
}
|
||||
|
||||
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<cMemorySettingsRepository> parseArguments(int argc, char **argv)
|
||||
std::unique_ptr<cMemorySettingsRepository> 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)
|
||||
|
||||
Reference in New Issue
Block a user