aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoritrofimow <itrofimow@yandex-team.com>2024-06-06 20:11:50 +0300
committeritrofimow <itrofimow@yandex-team.com>2024-06-06 20:21:56 +0300
commit0635c46df5826df8bb0dda8ad418442978c322ca (patch)
treeb6110d01c5841c2f8c4ff68249e20821a3cec057
parent537a7b1307461881b8abc1381ba9f79e6104f439 (diff)
downloadydb-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.cpp12
-rw-r--r--util/system/atexit.h9
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();