diff options
Diffstat (limited to 'src/zenserver/main.cpp')
| -rw-r--r-- | src/zenserver/main.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/zenserver/main.cpp b/src/zenserver/main.cpp index 6d9a478be..4ea4ee87e 100644 --- a/src/zenserver/main.cpp +++ b/src/zenserver/main.cpp @@ -24,6 +24,8 @@ #include <zencore/memory/memorytrace.h> #include <zencore/memory/newdelete.h> +#include <zenutil/service.h> + #include "config.h" #include "diag/logging.h" @@ -32,6 +34,12 @@ # include "windows/service.h" #endif +#if ZEN_PLATFORM_LINUX +ZEN_THIRD_PARTY_INCLUDES_START +# include <systemd/sd-daemon.h> +ZEN_THIRD_PARTY_INCLUDES_END +#endif + ////////////////////////////////////////////////////////////////////////// // We don't have any doctest code in this file but this is needed to bring // in some shared code into the executable @@ -88,9 +96,48 @@ ZenEntryPoint::ZenEntryPoint(ZenServerOptions& ServerOptions) : m_ServerOptions( { } +void +ReportServiceStatus(ServiceStatus Status) +{ +#if ZEN_PLATFORM_WINDOWS + switch (Status) + { + case ServiceStatus::Starting: + ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000); + break; + case ServiceStatus::Running: + ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); + break; + case ServiceStatus::Stopping: + ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); + break; + case ServiceStatus::Stopped: + ReportSvcStatus(SERVICE_STOPPED, (DWORD)ApplicationExitCode(), 0); + break; + default: + break; + } +#elif ZEN_PLATFORM_LINUX + switch (Status) + { + case ServiceStatus::Running: + sd_notify(0, "READY=1"); + break; + case ServiceStatus::Stopping: + sd_notify(0, "STOPPING=1"); + break; + case ServiceStatus::Stopped: + sd_notifyf(0, "EXIT_STATUS=%d", ApplicationExitCode()); + break; + } +#endif + (void)Status; +} + int ZenEntryPoint::Run() { + ZEN_INFO("ZenEntryPoint::Run()"); zen::SetCurrentThreadName("main"); #if ZEN_USE_SENTRY @@ -113,8 +160,11 @@ ZenEntryPoint::Run() try { // Mutual exclusion and synchronization + ZEN_INFO("ZenServerState ServerState"); ZenServerState ServerState; + ZEN_INFO("ServerState.Initialize()"); ServerState.Initialize(); + ZEN_INFO("ServerState.Sweep()"); ServerState.Sweep(); auto NotifyReady = [&] { @@ -188,6 +238,8 @@ ZenEntryPoint::Run() } } + ZEN_INFO("Preparing lock file"); + std::error_code Ec; std::filesystem::path LockFilePath = m_ServerOptions.DataDir / ".lock"; @@ -201,6 +253,7 @@ ZenEntryPoint::Run() .ExecutablePath = GetRunningExecutablePath()}); }; + ZEN_INFO("m_LockFile.Create"); m_LockFile.Create(LockFilePath, MakeLockData(false), Ec); if (Ec) @@ -216,6 +269,7 @@ ZenEntryPoint::Run() } } + ZEN_INFO("InitializeServerLogging"); InitializeServerLogging(m_ServerOptions); ZEN_INFO("Command line: {}", m_ServerOptions.CommandLine); @@ -288,6 +342,8 @@ ZenEntryPoint::Run() }}); auto CleanupShutdown = MakeGuard([&ShutdownEvent, &ShutdownThread] { + ReportServiceStatus(ServiceStatus::Stopping); + if (ShutdownEvent) { ShutdownEvent->Set(); @@ -303,6 +359,7 @@ ZenEntryPoint::Run() Server.SetIsReadyFunc([&] { m_LockFile.Update(MakeLockData(true), Ec); + ReportServiceStatus(ServiceStatus::Running); NotifyReady(); }); @@ -313,6 +370,14 @@ ZenEntryPoint::Run() ZEN_CRITICAL("Caught assert exception in main for process {}: {}", zen::GetCurrentProcessId(), AssertEx.FullDescription()); RequestApplicationExit(1); } + catch (const std::system_error& e) + { + ZEN_CRITICAL("Caught system error exception in main for process {}: {} ({})", + zen::GetCurrentProcessId(), + e.what(), + e.code().value()); + RequestApplicationExit(1); + } catch (const std::exception& e) { ZEN_CRITICAL("Caught exception in main for process {}: {}", zen::GetCurrentProcessId(), e.what()); @@ -321,6 +386,8 @@ ZenEntryPoint::Run() ShutdownServerLogging(); + ReportServiceStatus(ServiceStatus::Stopped); + return ApplicationExitCode(); } @@ -390,6 +457,10 @@ main(int argc, char* argv[]) signal(SIGINT, utils::SignalCallbackHandler); signal(SIGTERM, utils::SignalCallbackHandler); +#if ZEN_PLATFORM_LINUX + IgnoreChildSignals(); +#endif + try { ZenServerOptions ServerOptions; |