ircd: Add infrastructure to handle continuation notification after suspending.

This commit is contained in:
Jason Volk 2019-06-05 15:06:16 -07:00
parent 855a5f5a1e
commit f702520044
4 changed files with 80 additions and 16 deletions

View File

@ -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 This signal commands the server to reload and refresh various aspects of its
configuration and running state. 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.

View File

@ -18,6 +18,7 @@ namespace construct
{ {
namespace ph = std::placeholders; namespace ph = std::placeholders;
static void handle_cont();
static void handle_usr1(); static void handle_usr1();
static void handle_quit(); static void handle_quit();
static void handle_interrupt(); static void handle_interrupt();
@ -40,6 +41,7 @@ construct::signals::signals(boost::asio::io_context &ios)
signal_set->add(SIGQUIT); signal_set->add(SIGQUIT);
signal_set->add(SIGTERM); signal_set->add(SIGTERM);
signal_set->add(SIGUSR1); signal_set->add(SIGUSR1);
signal_set->add(SIGCONT);
set_handle(); set_handle();
} }
@ -115,11 +117,12 @@ construct::handle_signal(const int &signum)
{ {
switch(signum) switch(signum)
{ {
case SIGINT: return handle_interrupt();
case SIGHUP: return handle_hangup(); case SIGHUP: return handle_hangup();
case SIGINT: return handle_interrupt();
case SIGQUIT: return handle_quit(); case SIGQUIT: return handle_quit();
case SIGTERM: return handle_quit(); case SIGTERM: return handle_quit();
case SIGUSR1: return handle_usr1(); case SIGUSR1: return handle_usr1();
case SIGCONT: return handle_cont();
default: break; 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 void
construct::handle_hangup() construct::handle_hangup()
try 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 void
construct::handle_usr1() construct::handle_usr1()
try try
@ -219,3 +222,17 @@ catch(const std::exception &e)
"SIGUSR1 handler: %s", e.what() "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()
};
}

View File

@ -69,8 +69,10 @@
namespace ircd namespace ircd
{ {
seconds uptime(); seconds uptime();
void init(boost::asio::io_context &ios, const string_view &origin, const string_view &hostname);
void cont() noexcept;
bool quit() noexcept; bool quit() noexcept;
void init(boost::asio::io_context &ios, const string_view &origin, const string_view &hostname);
extern conf::item<bool> restart; extern conf::item<bool> restart;
extern conf::item<bool> debugmode; extern conf::item<bool> debugmode;

View File

@ -201,6 +201,44 @@ noexcept
return false; 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. /// Main context; Main program. Do not call this function directly.
/// ///
/// This function manages the lifetime for all resources and subsystems /// This function manages the lifetime for all resources and subsystems