aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/sighandler
diff options
context:
space:
mode:
authorarkady-e1ppa <arkady-e1ppa@yandex-team.com>2023-11-03 01:56:51 +0300
committerarkady-e1ppa <arkady-e1ppa@yandex-team.com>2023-11-03 02:17:18 +0300
commit1ff41fbc8d84eb71ae278c62500546cedab8dce2 (patch)
tree176c932f6ee293c097393f0f0a8c5a06ba60c637 /library/cpp/sighandler
parent47a733af080e57d9d3d7659b2458d9b21eaf7f18 (diff)
downloadydb-1ff41fbc8d84eb71ae278c62500546cedab8dce2.tar.gz
YT-20376: TAsyncSignalsHandler improved thread safety
First commit
Diffstat (limited to 'library/cpp/sighandler')
-rw-r--r--library/cpp/sighandler/async_signals_handler.cpp21
1 files changed, 16 insertions, 5 deletions
diff --git a/library/cpp/sighandler/async_signals_handler.cpp b/library/cpp/sighandler/async_signals_handler.cpp
index 0c20dfccaa..ac3771f0d5 100644
--- a/library/cpp/sighandler/async_signals_handler.cpp
+++ b/library/cpp/sighandler/async_signals_handler.cpp
@@ -188,22 +188,33 @@ namespace {
// It such situation we have 2 options:
// - wait for auxiliary thread to die - which will cause dead lock
// - destruct variable, ignoring thread - which will cause data corruption.
- TAsyncSignalsHandler* SIGNALS_HANDLER = nullptr;
+ std::atomic<TAsyncSignalsHandler*> SIGNALS_HANDLER = nullptr;
}
void SetAsyncSignalHandler(int signum, THolder<TEventHandler> handler) {
static TAdaptiveLock lock;
- if (Y_UNLIKELY(SIGNALS_HANDLER == nullptr)) {
+ // Must be in HB with Handler's constructor.
+ auto* currentHandler = SIGNALS_HANDLER.load(std::memory_order::acquire);
+
+ if (Y_UNLIKELY(currentHandler == nullptr)) {
TGuard dnd(lock);
- if (SIGNALS_HANDLER == nullptr) {
+ // If we read non-null here it means that we have a concurrent thread
+ // unlocking the lock establishing strongly HB with us.
+ // next line is sequenced before lock call thus relaxed is enough here.
+ currentHandler = SIGNALS_HANDLER.load(std::memory_order::relaxed);
+
+ if (currentHandler == nullptr) {
// NEVERS GETS DESTROYED
- SIGNALS_HANDLER = new TAsyncSignalsHandler();
+ currentHandler = new TAsyncSignalsHandler();
+
+ // Ensure HB with constructor for future readers.
+ SIGNALS_HANDLER.store(currentHandler, std::memory_order::release);
}
}
- SIGNALS_HANDLER->Install(signum, std::move(handler));
+ currentHandler->Install(signum, std::move(handler));
}
#else //_win_