1
0

Fixed and improved restarting

Restarts are now an actual, close-as-possible to application
exit+reopen.
This commit is contained in:
Tiger Wang
2015-06-17 15:38:00 +01:00
parent b5ed23d2a6
commit 4315a11393
7 changed files with 253 additions and 211 deletions

View File

@@ -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)