Program Listing for File signal_handling.cpp¶
↰ Return to documentation for file (src/common/signal_handling.cpp
)
#include "common/logging.h"
#include "signal_handling.h"
// The simplest (and recommended) way to handle signals is to simply set a flag
// in the signal handler and check that flag later.
//
// We provide setSignalFlag as the most generic signal handler. This handler uses a
// single sig_atomic_t as a bit field. On Linux, sig_atomic_t is equivalent to a signed int,
// theoretically providing 32 binary flags; in practice, most likely signals for which we may
// want to install signal handlers are
// - SIGTERM (15): which by default signals the request for a graceful shutdown
// - SIGUSR1 (10): intended for custom use, default action in Linux is termination
// - SIGUSR2 (12): intended for custom use, default action in Linux is termination
// - SIGINT (2): interrupt from the console
// Just to be safe, we accommodate signals up to signal No. 30.
// In addition, we also provide requestSaveAndExit() and saveAndExit() as a signal
// handler/checker for graceful shutdown requests during training.
constexpr int maxSignalForSetSignalFlag{30};
// Make sure sig_atomic_t is large enough as a bit field for our purposes.
// That said, I'm not aware of any platform where this would be a problem.
static_assert(SIG_ATOMIC_MAX > (1U<<maxSignalForSetSignalFlag),
"sig_atomic_type is too small for signal flags on this platform.");
namespace marian{
volatile std::sig_atomic_t sigflags_{0};
volatile std::sig_atomic_t saveAndExit_{0};
void setSignalFlag(int sig) {
// sigflags_ is an int type serving as a bit filed for flags corresponding
// to signals (lower or equeal to maxSignalForSetSignalFlag). We set the
// flag by a binary or (|=) of the bit field and an int value with exactly
// one bit set (s^sig).
sigflags_ |= (1<<sig);
}
// Check if the flag for the signal sig is set in the bit field sigflags_
bool getSignalFlag(const int sig) {
ABORT_IF(sig > maxSignalForSetSignalFlag,
"Signal out of range (must be < {}, is {}).", maxSignalForSetSignalFlag, sig);
// Do bitwise AND between sigflags_ and an int value that has exactly one bit set that
// corresponds to the signal in question. If the bit is set (see setSignalFlag above),
// the bitwise AND will return a non-zero integer, if it is not set, the result will
// be zero.
return (sigflags_ & (1<<sig)) != 0;
}
void requestSaveAndExit(int sig) {
setSignalFlag(sig); // keep track of triggering signal
saveAndExit_ = 1; // set flag to exit gracefully
}
bool saveAndExitRequested() {
return saveAndExit_ == 1;
}
}