about summary refs log tree commit diff
path: root/src/libstd/rt/unwind.rs
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-12-19 11:29:39 -0800
committerAlex Crichton <alex@alexcrichton.com>2014-12-30 14:33:59 -0800
commit9e224c2bf18ebf8f871efb2e1aba43ed7970ebb7 (patch)
treeda18d5791e6841a1aa6a9469baca155d4ca9828d /src/libstd/rt/unwind.rs
parentd2368c3c11ddab9d812c4ddec2e44579326ad347 (diff)
std: Re-enable at_exit()
The new semantics of this function are that the callbacks are run when the *main
thread* exits, not when all threads have exited. This implies that other threads
may still be running when the `at_exit` callbacks are invoked and users need to
be prepared for this situation.

Users in the standard library have been audited in accordance to these new rules
as well.

Closes #20012
Diffstat (limited to 'src/libstd/rt/unwind.rs')
-rw-r--r--src/libstd/rt/unwind.rs17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index 9b57dcc9e18..32fa126ded4 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -68,7 +68,7 @@ use intrinsics;
 use libc::c_void;
 use mem;
 use sync::atomic;
-use sync::{Once, ONCE_INIT};
+use sys_common::mutex::{Mutex, MUTEX_INIT};
 
 use rt::libunwind as uw;
 
@@ -587,11 +587,20 @@ pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, uint)) ->
 /// Doing this split took the LLVM IR line counts of `fn main() { panic!()
 /// }` from ~1900/3700 (-O/no opts) to 180/590.
 #[inline(never)] #[cold] // this is the slow path, please never inline this
-fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) -> ! {
+fn begin_unwind_inner(msg: Box<Any + Send>,
+                      file_line: &(&'static str, uint)) -> ! {
     // Make sure the default failure handler is registered before we look at the
     // callbacks.
-    static INIT: Once = ONCE_INIT;
-    INIT.doit(|| unsafe { register(failure::on_fail); });
+    unsafe {
+        static LOCK: Mutex = MUTEX_INIT;
+        static mut INIT: bool = false;
+        LOCK.lock();
+        if !INIT {
+            register(failure::on_fail);
+            INIT = true;
+        }
+        LOCK.unlock();
+    }
 
     // First, invoke call the user-defined callbacks triggered on thread panic.
     //