summaryrefslogtreecommitdiffstats
path: root/library/std/src/sys/common/thread_local/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/sys/common/thread_local/mod.rs')
-rw-r--r--library/std/src/sys/common/thread_local/mod.rs21
1 files changed, 21 insertions, 0 deletions
diff --git a/library/std/src/sys/common/thread_local/mod.rs b/library/std/src/sys/common/thread_local/mod.rs
index 77f645883..975509bd4 100644
--- a/library/std/src/sys/common/thread_local/mod.rs
+++ b/library/std/src/sys/common/thread_local/mod.rs
@@ -101,3 +101,24 @@ mod lazy {
}
}
}
+
+/// Run a callback in a scenario which must not unwind (such as a `extern "C"
+/// fn` declared in a user crate). If the callback unwinds anyway, then
+/// `rtabort` with a message about thread local panicking on drop.
+#[inline]
+pub fn abort_on_dtor_unwind(f: impl FnOnce()) {
+ // Using a guard like this is lower cost.
+ let guard = DtorUnwindGuard;
+ f();
+ core::mem::forget(guard);
+
+ struct DtorUnwindGuard;
+ impl Drop for DtorUnwindGuard {
+ #[inline]
+ fn drop(&mut self) {
+ // This is not terribly descriptive, but it doesn't need to be as we'll
+ // already have printed a panic message at this point.
+ rtabort!("thread local panicked on drop");
+ }
+ }
+}