diff options
author | Arnstein Ressem <aressem@verizonmedia.com> | 2020-04-02 15:13:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-02 15:13:44 +0200 |
commit | 7507e2bf9fb8f8aa384bc1aa0d5cbedd5ecb447b (patch) | |
tree | 7815c3ffe8d41ca8d974e63f644ec70e081e00b2 | |
parent | eb6b9add4b7d0c62d8e2a6d701b2854011910eee (diff) | |
parent | 9e8284c76aafa09b196563ae99d0d0a43d19414e (diff) |
Merge pull request #12808 from vespa-engine/toregge/improve-signal-handler-shutdown-robustness
Improve SignalHandler::shutdown robustness.
-rw-r--r-- | vespalib/src/vespa/vespalib/util/signalhandler.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/vespalib/src/vespa/vespalib/util/signalhandler.cpp b/vespalib/src/vespa/vespalib/util/signalhandler.cpp index 0a5eea0d327..c4fb7cfa517 100644 --- a/vespalib/src/vespa/vespalib/util/signalhandler.cpp +++ b/vespalib/src/vespa/vespalib/util/signalhandler.cpp @@ -2,6 +2,11 @@ #include "signalhandler.h" #include <cassert> +#include <atomic> +#include <chrono> +#include <thread> + +using namespace std::chrono_literals; namespace vespalib { @@ -9,6 +14,9 @@ std::vector<SignalHandler*> SignalHandler::_handlers; namespace { +// 31 bit concurrency counter, 1 (lsb) bit indicating shutdown +std::atomic<int> signal_counter; + class Shutdown { public: @@ -39,9 +47,13 @@ Shutdown shutdown; void SignalHandler::handleSignal(int signal) { - if ((((size_t)signal) < _handlers.size()) && (_handlers[signal] != 0)) { - _handlers[signal]->gotSignal(); + static_assert(std::atomic<int>::is_always_lock_free, "signal_counter must be lock free"); + if ((signal_counter.fetch_add(2) & 1) == 0) { + if ((((size_t)signal) < _handlers.size()) && (_handlers[signal] != 0)) { + _handlers[signal]->gotSignal(); + } } + signal_counter.fetch_sub(2); } void @@ -108,6 +120,9 @@ SignalHandler::unhook() void SignalHandler::shutdown() { + while ((signal_counter.fetch_or(1) & ~1) != 0) { + std::this_thread::sleep_for(10ms); + } for (std::vector<SignalHandler*>::iterator it = _handlers.begin(), ite = _handlers.end(); it != ite; |