diff options
| author | Dan Engelbrecht <[email protected]> | 2023-05-11 16:54:16 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-05-11 16:54:16 +0200 |
| commit | 1250f1c71c3a734a7f04bc029516733f9e87ff27 (patch) | |
| tree | 0c61b42a409816219d0cc74b577fead9094efd35 /src/zenserver/zenserver.cpp | |
| parent | allow early logging (#292) (diff) | |
| download | zen-1250f1c71c3a734a7f04bc029516733f9e87ff27.tar.xz zen-1250f1c71c3a734a7f04bc029516733f9e87ff27.zip | |
Gracefully exit if Ctrl-C is pressed (#293)
* Feature: Gracefully exit if Ctrl-C is pressed
* Bugfix: Return error code on exit as set by application
* changelog
Diffstat (limited to 'src/zenserver/zenserver.cpp')
| -rw-r--r-- | src/zenserver/zenserver.cpp | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/src/zenserver/zenserver.cpp b/src/zenserver/zenserver.cpp index f9221ed0f..ce5e4e964 100644 --- a/src/zenserver/zenserver.cpp +++ b/src/zenserver/zenserver.cpp @@ -130,6 +130,16 @@ namespace zen { using namespace std::literals; namespace utils { + static std::atomic_uint32_t SignalCounter[NSIG] = {0}; + + static void SignalCallbackHandler(int SigNum) + { + if (SigNum >= 0 && SigNum < NSIG) + { + SignalCounter[SigNum].fetch_add(1); + } + } + #if ZEN_USE_SENTRY class sentry_sink final : public spdlog::sinks::base_sink<spdlog::details::null_mutex> { @@ -520,17 +530,36 @@ public: EnsureIoRunner(); } + void EnqueueSigIntTimer() + { + m_SigIntTimer.expires_after(std::chrono::milliseconds(500)); + m_SigIntTimer.async_wait([this](const asio::error_code&) { CheckSigInt(); }); + EnsureIoRunner(); + } + void CheckStateMarker() { std::filesystem::path StateMarkerPath = m_DataRoot / "state_marker"; if (!std::filesystem::exists(StateMarkerPath)) { ZEN_ERROR("state marker at {} has been deleted, exiting", StateMarkerPath); - RequestExit(0); + RequestExit(1); + return; } EnqueueStateMarkerTimer(); } + void CheckSigInt() + { + if (utils::SignalCounter[SIGINT] > 0) + { + ZEN_INFO("SIGINT triggered (Ctrl+C), exiting"); + RequestExit(128 + SIGINT); + return; + } + EnqueueSigIntTimer(); + } + void CheckOwnerPid() { // Pick up any new "owner" processes @@ -615,6 +644,7 @@ private: asio::io_context m_IoContext; asio::steady_timer m_PidCheckTimer{m_IoContext}; asio::steady_timer m_StateMakerTimer{m_IoContext}; + asio::steady_timer m_SigIntTimer{m_IoContext}; zen::ProcessMonitor m_ProcessMonitor; zen::NamedMutex m_ServerMutex; @@ -686,6 +716,8 @@ ZenServer::OnReady() void ZenServer::InitializeState(const ZenServerOptions& ServerOptions) { + EnqueueSigIntTimer(); + // Check root manifest to deal with schema versioning bool WipeState = false; @@ -1198,8 +1230,11 @@ ZenEntryPoint::Run() ZEN_INFO("shutdown monitor thread waiting for shutdown signal '{}'", ShutdownEventName); if (ShutdownEvent->Wait()) { - ZEN_INFO("shutdown signal received"); - Server.RequestExit(0); + if (!IsApplicationExitRequested()) + { + ZEN_INFO("shutdown signal received"); + Server.RequestExit(0); + } } else { @@ -1235,7 +1270,7 @@ ZenEntryPoint::Run() ShutdownLogging(); - return 0; + return ApplicationExitCode(); } } // namespace zen @@ -1306,6 +1341,8 @@ main(int argc, char* argv[]) } #endif + signal(SIGINT, utils::SignalCallbackHandler); + try { ZenServerOptions ServerOptions; |