summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-03-20 20:19:42 +0000
committerbors <bors@rust-lang.org>2015-03-20 20:19:42 +0000
commit68d69415637186755482d2584e6ba82b67bc1d89 (patch)
tree702068026393f26edf8b134f8dca0219dd1c0255 /src/libstd/rt
parent3900c089a1305f06c6dbb15d07127b4e3a8f040c (diff)
parent1cc9718fdef63476ffdf3f0bcd74b554b083f378 (diff)
downloadrust-68d69415637186755482d2584e6ba82b67bc1d89.tar.gz
rust-68d69415637186755482d2584e6ba82b67bc1d89.zip
Auto merge of #23267 - alexcrichton:issue-20012, r=aturon
This reverts commit aec67c2.

Closes #20012

This is temporarily rebased on #23245 as it would otherwise conflict, the last commit is the only one relevant to this PR though.
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/mod.rs21
-rw-r--r--src/libstd/rt/unwind.rs23
2 files changed, 23 insertions, 21 deletions
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 5e8abfd0a3f..e52e68dad23 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -147,20 +147,14 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
     }
 }
 
-/// Enqueues a procedure to run when the runtime is cleaned up
-///
-/// The procedure passed to this function will be executed as part of the
-/// runtime cleanup phase. For normal rust programs, this means that it will run
-/// after all other threads have exited.
-///
-/// The procedure is *not* executed with a local `Thread` available to it, so
-/// primitives like logging, I/O, channels, spawning, etc, are *not* available.
-/// This is meant for "bare bones" usage to clean up runtime details, this is
-/// not meant as a general-purpose "let's clean everything up" function.
+/// Enqueues a procedure to run when the main thread exits.
 ///
 /// It is forbidden for procedures to register more `at_exit` handlers when they
 /// are running, and doing so will lead to a process abort.
-pub fn at_exit<F:FnOnce()+Send+'static>(f: F) {
+///
+/// Note that other threads may still be running when `at_exit` routines start
+/// running.
+pub fn at_exit<F: FnOnce() + Send + 'static>(f: F) {
     at_exit_imp::push(Thunk::new(f));
 }
 
@@ -176,8 +170,5 @@ pub fn at_exit<F:FnOnce()+Send+'static>(f: F) {
 pub unsafe fn cleanup() {
     args::cleanup();
     sys::stack_overflow::cleanup();
-    // FIXME: (#20012): the resources being cleaned up by at_exit
-    // currently are not prepared for cleanup to happen asynchronously
-    // with detached threads using the resources; for now, we leak.
-    // at_exit_imp::cleanup();
+    at_exit_imp::cleanup();
 }
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index ebb2a2e4827..3ee3954ed64 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -69,7 +69,7 @@ use intrinsics;
 use libc::c_void;
 use mem;
 use sync::atomic::{self, Ordering};
-use sync::{Once, ONCE_INIT};
+use sys_common::mutex::{Mutex, MUTEX_INIT};
 
 use rt::libunwind as uw;
 
@@ -534,11 +534,22 @@ 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)) -> ! {
-    // Make sure the default panic handler is registered before we look at the
-    // callbacks.
-    static INIT: Once = ONCE_INIT;
-    INIT.call_once(|| unsafe { register(panicking::on_panic); });
+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. We also use a raw sys-based mutex here instead of a
+    // `std::sync` one as accessing TLS can cause weird recursive problems (and
+    // we don't need poison checking).
+    unsafe {
+        static LOCK: Mutex = MUTEX_INIT;
+        static mut INIT: bool = false;
+        LOCK.lock();
+        if !INIT {
+            register(panicking::on_panic);
+            INIT = true;
+        }
+        LOCK.unlock();
+    }
 
     // First, invoke call the user-defined callbacks triggered on thread panic.
     //