campaignd: Only quit to SIGINT and SIGTERM after a processing cycle

Otherwise we run the risk (as seen with the 2016-10-07~09 downtime
incident) of calling exit() while we're in the middle of writing WML
content to disk, in particular the add-ons list and server configuration
file. Trust me, no-one will be very impressed if you make them sort out
the mess that this kind of thing leaves behind.

Ideally we should atomically rename a temporary into the destination
file for each WML write we do here to avoid similar ugliness with
signals we don't/can't/mustn't handle (especially SIGKILL). It's always
best to stay on the safe side and assume that a botched write could kill
people.
This commit is contained in:
Ignacio R. Morelle 2016-10-09 03:53:52 -03:00
parent 56a14943cb
commit 019e7a72c7

View file

@ -70,6 +70,14 @@ namespace {
* (e.g. after SIGHUP).
*/
sig_atomic_t need_reload = 0;
/**
* Whether we've been requested to quit via SIGINT.
*/
sig_atomic_t sigint_exit = 0;
/**
* Whether we've been requested to quit via SIGTERM.
*/
sig_atomic_t sigterm_exit = 0;
void flag_sighup(int signal)
{
@ -78,18 +86,18 @@ void flag_sighup(int signal)
need_reload = 1;
}
void exit_sigint(int signal)
void flag_sigint(int signal)
{
assert(signal == SIGINT);
LOG_CS << "SIGINT caught, exiting without cleanup immediately.\n";
exit(0);
LOG_CS << "SIGINT caught, exiting...\n";
sigint_exit = 1;
}
void exit_sigterm(int signal)
void flag_sigterm(int signal)
{
assert(signal == SIGTERM);
LOG_CS << "SIGTERM caught, exiting without cleanup immediately.\n";
exit(128 + SIGTERM);
LOG_CS << "SIGTERM caught, exiting...\n";
sigterm_exit = 1;
}
time_t monotonic_clock()
@ -154,8 +162,8 @@ server::server(const std::string& cfg_file, size_t min_threads, size_t max_threa
#ifndef _MSC_VER
signal(SIGHUP, flag_sighup);
#endif
signal(SIGINT, exit_sigint);
signal(SIGTERM, exit_sigterm);
signal(SIGINT, flag_sigint);
signal(SIGTERM, flag_sigterm);
LOG_CS << "Port: " << port_ << " Worker threads min/max: " << min_threads
<< '/' << max_threads << '\n';
@ -330,7 +338,7 @@ void server::run()
time_t last_ts = monotonic_clock();
for(;;)
while(!sigterm_exit && !sigint_exit)
{
if(need_reload) {
load_config(); // TODO: handle port number config changes
@ -464,6 +472,12 @@ void server::run()
SDL_Delay(20);
}
if(sigint_exit) {
std::exit(0);
} else if(sigterm_exit) {
std::exit(128 + SIGTERM);
}
}
void server::register_handler(const std::string& cmd, const request_handler& func)