From f7025200449c8208ca6136e5a23340b3d28c8516 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Wed, 5 Jun 2019 15:06:16 -0700 Subject: [PATCH] ircd: Add infrastructure to handle continuation notification after suspending. --- construct/README.md | 7 +++++++ construct/signals.cc | 47 ++++++++++++++++++++++++++++++-------------- include/ircd/ircd.h | 4 +++- ircd/ircd.cc | 38 +++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 16 deletions(-) diff --git a/construct/README.md b/construct/README.md index 48ac7fc03..fd45dd351 100644 --- a/construct/README.md +++ b/construct/README.md @@ -46,3 +46,10 @@ server configuration et al is moved to `SIGUSR1`. This signal commands the server to reload and refresh various aspects of its configuration and running state. + +##### SIGCONT + +This signal is used to notify the server that execution has resumed after an +unexpected gap. We call `ircd::cont()` after receiving this signal. Examples +for when the server benefits from calling `ircd::cont()` are: after a previous +stop signal, debugging, or ACPI suspend and resume, etc. diff --git a/construct/signals.cc b/construct/signals.cc index 622357546..dfa3c3cc0 100644 --- a/construct/signals.cc +++ b/construct/signals.cc @@ -18,6 +18,7 @@ namespace construct { namespace ph = std::placeholders; + static void handle_cont(); static void handle_usr1(); static void handle_quit(); static void handle_interrupt(); @@ -40,6 +41,7 @@ construct::signals::signals(boost::asio::io_context &ios) signal_set->add(SIGQUIT); signal_set->add(SIGTERM); signal_set->add(SIGUSR1); + signal_set->add(SIGCONT); set_handle(); } @@ -115,11 +117,12 @@ construct::handle_signal(const int &signum) { switch(signum) { - case SIGINT: return handle_interrupt(); case SIGHUP: return handle_hangup(); + case SIGINT: return handle_interrupt(); case SIGQUIT: return handle_quit(); case SIGTERM: return handle_quit(); case SIGUSR1: return handle_usr1(); + case SIGCONT: return handle_cont(); default: break; } @@ -129,20 +132,6 @@ construct::handle_signal(const int &signum) }; } -void -construct::handle_quit() -try -{ - ircd::quit(); -} -catch(const std::exception &e) -{ - ircd::log::error - { - "SIGQUIT handler: %s", e.what() - }; -} - void construct::handle_hangup() try @@ -181,6 +170,20 @@ catch(const std::exception &e) }; } +void +construct::handle_quit() +try +{ + ircd::quit(); +} +catch(const std::exception &e) +{ + ircd::log::error + { + "SIGQUIT handler: %s", e.what() + }; +} + void construct::handle_usr1() try @@ -219,3 +222,17 @@ catch(const std::exception &e) "SIGUSR1 handler: %s", e.what() }; } + +void +construct::handle_cont() +try +{ + ircd::cont(); +} +catch(const std::exception &e) +{ + ircd::log::error + { + "SIGCONT handler: %s", e.what() + }; +} diff --git a/include/ircd/ircd.h b/include/ircd/ircd.h index 2b8c205a7..4fc863aef 100644 --- a/include/ircd/ircd.h +++ b/include/ircd/ircd.h @@ -69,8 +69,10 @@ namespace ircd { seconds uptime(); - void init(boost::asio::io_context &ios, const string_view &origin, const string_view &hostname); + + void cont() noexcept; bool quit() noexcept; + void init(boost::asio::io_context &ios, const string_view &origin, const string_view &hostname); extern conf::item restart; extern conf::item debugmode; diff --git a/ircd/ircd.cc b/ircd/ircd.cc index 48251df36..1c461bf16 100644 --- a/ircd/ircd.cc +++ b/ircd/ircd.cc @@ -201,6 +201,44 @@ noexcept return false; } +/// Notifies IRCd that execution is being resumed after a significant gap. +/// Basically this is connected to a SIGCONT handler and beneficial after +/// user stops, debugging and ACPI suspensions, etc. It is not required at +/// this time, but its connection is advised for best behavior. +void +ircd::cont() +noexcept +{ + log::debug + { + "IRCd cont requested from runlevel:%s ctx:%p main_context:%p", + reflect(run::level), + (const void *)ctx::current, + (const void *)main_context + }; + + switch(run::level) + { + case run::level::HALT: + case run::level::READY: + case run::level::FAULT: + return; + + case run::level::START: + case run::level::QUIT: + return; + + case run::level::RUN: + break; + } + + log::notice + { + "IRCd resuming service in runlevel:%s.", + reflect(run::level), + }; +} + /// Main context; Main program. Do not call this function directly. /// /// This function manages the lifetime for all resources and subsystems