aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/zenserver.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2023-05-11 16:54:16 +0200
committerGitHub <[email protected]>2023-05-11 16:54:16 +0200
commit1250f1c71c3a734a7f04bc029516733f9e87ff27 (patch)
tree0c61b42a409816219d0cc74b577fead9094efd35 /src/zenserver/zenserver.cpp
parentallow early logging (#292) (diff)
downloadzen-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.cpp45
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;