diff --git a/CHANGELOG.md b/CHANGELOG.md index 56513e2c702a3..756a167697eed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ ### Changed (changing behavior/API/variables/...) +- [[PR 782]](https://github.com/parthenon-hpc-lab/parthenon/pull/782) Die on repeatedly receiving SIGINT - [[PR 1438]](https://github.com/parthenon-hpc-lab/parthenon/pull/1438) Performance tuning for the loop abstraction machinery and add loop abstraction OpenMP support - [[PR 1416][(https://github.com/parthenon-hpc-lab/parthenon/pull/1416) Remove virtual tag from destructors in sparse and swarm pack base classes - [[PR 1401]](https://github.com/parthenon-hpc-lab/parthenon/pull/1401) Sparse Field Component Names diff --git a/src/utils/signal_handler.cpp b/src/utils/signal_handler.cpp index 7b54540f13fcb..b0bc06143b125 100644 --- a/src/utils/signal_handler.cpp +++ b/src/utils/signal_handler.cpp @@ -23,6 +23,7 @@ // first 2x macros and signal() are the only ISO C features; rest are POSIX C extensions #include +#include #include #include FS_HEADER @@ -132,15 +133,17 @@ void SetSignalFlag(int s) { // Signal handler functions must have C linkage; C++ linkage is implemantation-defined switch (s) { case SIGTERM: - signalflag[ITERM] = 1; + signalflag[ITERM] += 1; signal(s, SetSignalFlag); break; case SIGINT: - signalflag[IINT] = 1; + signalflag[IINT] += 1; + if (signalflag[IINT] >= SIGINTS_BEFORE_THROW) + PARTHENON_THROW("Terminating immediately on repeated Terminate signal"); signal(s, SetSignalFlag); break; case SIGALRM: - signalflag[IALRM] = 1; + signalflag[IALRM] += 1; signal(s, SetSignalFlag); break; default: diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp index d83cf297a4338..070667b12366c 100644 --- a/src/utils/utils.hpp +++ b/src/utils/utils.hpp @@ -91,11 +91,18 @@ void WatchDog(int timeout); // \brief static data and functions that implement a simple signal handling system namespace SignalHandler { +// Enum of desired signal results enum class OutputSignal { none, now, final, analysis }; +// Signals handled: SIGTERM, SIGINT, SIGALRM +constexpr int ITERM = 0, IINT = 1, IALRM = 2; constexpr int nsignal = 3; -// using the +1 for signaling based on "output_now" trigger +// Flag/counter of signals received of each type +// using the +1 for signaling based on a trigger file static volatile int signalflag[nsignal + 1]; -const int ITERM = 0, IINT = 1, IALRM = 2; + +// Immediately throw upon receiving 3+ SIGINT without clearing them +constexpr int SIGINTS_BEFORE_THROW = 3; + static sigset_t mask; void SignalHandlerInit(); OutputSignal CheckSignalFlags();