diff options
author | itrofimow <itrofimow@yandex-team.com> | 2024-06-06 20:11:50 +0300 |
---|---|---|
committer | itrofimow <itrofimow@yandex-team.com> | 2024-06-06 20:21:56 +0300 |
commit | 0635c46df5826df8bb0dda8ad418442978c322ca (patch) | |
tree | b6110d01c5841c2f8c4ff68249e20821a3cec057 | |
parent | 537a7b1307461881b8abc1381ba9f79e6104f439 (diff) | |
download | ydb-0635c46df5826df8bb0dda8ad418442978c322ca.tar.gz |
feat util/system: add a possibility to disable exit handlers, use it in rate-limiter nginx module
b90ea2b46b910c5bf2e0db4ccacb45ca5c39ecaa
-rw-r--r-- | util/system/atexit.cpp | 12 | ||||
-rw-r--r-- | util/system/atexit.h | 9 |
2 files changed, 21 insertions, 0 deletions
diff --git a/util/system/atexit.cpp b/util/system/atexit.cpp index 7fafad95a6..09fa7d8381 100644 --- a/util/system/atexit.cpp +++ b/util/system/atexit.cpp @@ -36,6 +36,9 @@ namespace { inline void Finish() noexcept { FinishStarted_.store(true); + if (ExitHandlersDisabled_.load()) { + return; + } auto guard = Guard(Lock_); @@ -69,11 +72,16 @@ namespace { return FinishStarted_.load(); } + inline void DisableExitHandlers() { + ExitHandlersDisabled_.store(true); + } + private: TAdaptiveLock Lock_; std::atomic<bool> FinishStarted_; TDeque<TFunc> Store_; TPriorityQueue<TFunc*, TVector<TFunc*>, TCmp> Items_; + std::atomic<bool> ExitHandlersDisabled_{false}; }; static TAdaptiveLock atExitLock; @@ -134,3 +142,7 @@ void AtExit(TTraditionalAtExitFunc func) { void AtExit(TTraditionalAtExitFunc func, size_t priority) { AtExit(TraditionalCloser, reinterpret_cast<void*>(func), priority); } + +void DisableExitHandlers() { + Instance()->DisableExitHandlers(); +} diff --git a/util/system/atexit.h b/util/system/atexit.h index eb3188615c..72096ec9e2 100644 --- a/util/system/atexit.h +++ b/util/system/atexit.h @@ -20,3 +20,12 @@ bool ExitStarted(); * Calls in the moment when application is not terminating - bad idea. */ void ManualRunAtExitFinalizers(); + +/** + * You shouldn't ever need this, unless you are writing some DLL modules, + * which might get unloaded before application termination (nginx's modules, for example). + * If a DLL sets exit handlers which belong to the DLL itself, these handlers point to + * nowhere after the DLL has been unloaded, and an attempt to invoke any of those at the + * application termination leads to a crash. + */ +void DisableExitHandlers(); |