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:
parent
56a14943cb
commit
019e7a72c7
1 changed files with 23 additions and 9 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue