about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-12-17 14:59:20 -0800
committerAaron Turon <aturon@mozilla.com>2014-12-18 23:35:52 -0800
commitd08600b189eeb2e61879b44a07f9fdc33fa82689 (patch)
tree274743c02df19bff0de04f5c9098f8c280d29c23 /src/libstd
parent5759cff48e66bcf2bf2cf821211bdf683292d8f3 (diff)
downloadrust-d08600b189eeb2e61879b44a07f9fdc33fa82689.tar.gz
rust-d08600b189eeb2e61879b44a07f9fdc33fa82689.zip
std: Move the panic flag to its own thread local
This flag is somewhat tied to the `unwind` module rather than the `thread_info`
module, so this commit moves it into that module as well as allowing the same OS
thread to call `unwind::try` multiple times. Previously once a thread panicked
its panic flag was never reset, even after exiting the panic handler.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/failure.rs16
-rw-r--r--src/libstd/rt/unwind.rs19
-rw-r--r--src/libstd/sys/common/thread_info.rs11
-rw-r--r--src/libstd/thread.rs2
4 files changed, 21 insertions, 27 deletions
diff --git a/src/libstd/failure.rs b/src/libstd/failure.rs
index 3934b0cf45f..8e1e3dc4af9 100644
--- a/src/libstd/failure.rs
+++ b/src/libstd/failure.rs
@@ -10,21 +10,15 @@
 
 #![experimental]
 
-use alloc::boxed::Box;
+use prelude::*;
+
 use any::{Any, AnyRefExt};
 use cell::RefCell;
 use fmt;
-use io::{Writer, IoResult};
-use kinds::Send;
-use option::Option;
-use option::Option::{Some, None};
-use result::Result::Ok;
-use rt::backtrace;
+use io::IoResult;
+use rt::{backtrace, unwind};
 use rt::util::{Stderr, Stdio};
-use str::Str;
-use string::String;
 use thread::Thread;
-use sys_common::thread_info;
 
 // Defined in this module instead of io::stdio so that the unwinding
 thread_local! {
@@ -80,7 +74,7 @@ pub fn on_fail(obj: &(Any+Send), file: &'static str, line: uint) {
 
     // If this is a double panic, make sure that we printed a backtrace
     // for this panic.
-    if thread_info::panicking() && !backtrace::log_enabled() {
+    if unwind::panicking() && !backtrace::log_enabled() {
         let _ = backtrace::write(&mut err);
     }
 }
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index 8ef10cbbd77..9f34a72f807 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -60,6 +60,7 @@
 use prelude::*;
 
 use any::Any;
+use cell::Cell;
 use cmp;
 use failure;
 use fmt;
@@ -69,7 +70,6 @@ use mem;
 use sync::atomic;
 use sync::{Once, ONCE_INIT};
 
-use sys_common::thread_info;
 use rt::libunwind as uw;
 
 struct Exception {
@@ -94,6 +94,8 @@ static CALLBACKS: [atomic::AtomicUint, ..MAX_CALLBACKS] =
          atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT];
 static CALLBACK_CNT: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
 
+thread_local!(static PANICKING: Cell<bool> = Cell::new(false))
+
 /// Invoke a closure, capturing the cause of panic if one occurs.
 ///
 /// This function will return `None` if the closure did not panic, and will
@@ -116,7 +118,11 @@ static CALLBACK_CNT: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
 ///   run.
 pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
     let mut f = Some(f);
+
+    let prev = PANICKING.with(|s| s.get());
+    PANICKING.with(|s| s.set(false));
     let ep = rust_try(try_fn::<F>, &mut f as *mut _ as *mut c_void);
+    PANICKING.with(|s| s.set(prev));
     return if ep.is_null() {
         Ok(())
     } else {
@@ -146,6 +152,11 @@ pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
     }
 }
 
+/// Test if the current thread is currently panicking.
+pub fn panicking() -> bool {
+    PANICKING.with(|s| s.get())
+}
+
 // An uninlined, unmangled function upon which to slap yer breakpoints
 #[inline(never)]
 #[no_mangle]
@@ -561,15 +572,15 @@ fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) ->
 
     // Now that we've run all the necessary unwind callbacks, we actually
     // perform the unwinding.
-    if thread_info::panicking() {
+    if panicking() {
         // If a thread panics while it's already unwinding then we
         // have limited options. Currently our preference is to
         // just abort. In the future we may consider resuming
         // unwinding or otherwise exiting the task cleanly.
-        rterrln!("task failed during unwinding. aborting.");
+        rterrln!("thread panicked while panicking. aborting.");
         unsafe { intrinsics::abort() }
     }
-    thread_info::set_unwinding(true);
+    PANICKING.with(|s| s.set(true));
     rust_panic(msg);
 }
 
diff --git a/src/libstd/sys/common/thread_info.rs b/src/libstd/sys/common/thread_info.rs
index 92a896c7583..0519bc56f0a 100644
--- a/src/libstd/sys/common/thread_info.rs
+++ b/src/libstd/sys/common/thread_info.rs
@@ -20,7 +20,6 @@ struct ThreadInfo {
     // hence this is optional.
     stack_bounds: (uint, uint),
     stack_guard: uint,
-    unwinding: bool,
     thread: Thread,
 }
 
@@ -38,7 +37,6 @@ impl ThreadInfo {
                 *c.borrow_mut() = Some(ThreadInfo {
                     stack_bounds: (0, 0),
                     stack_guard: 0,
-                    unwinding: false,
                     thread: NewThread::new(None),
                 })
             }
@@ -51,24 +49,15 @@ pub fn current_thread() -> Thread {
     ThreadInfo::with(|info| info.thread.clone())
 }
 
-pub fn panicking() -> bool {
-    ThreadInfo::with(|info| info.unwinding)
-}
-
 pub fn stack_guard() -> uint {
     ThreadInfo::with(|info| info.stack_guard)
 }
 
-pub fn set_unwinding(unwinding: bool) {
-    ThreadInfo::with(|info| info.unwinding = unwinding)
-}
-
 pub fn set(stack_bounds: (uint, uint), stack_guard: uint, thread: Thread) {
     THREAD_INFO.with(|c| assert!(c.borrow().is_none()));
     THREAD_INFO.with(move |c| *c.borrow_mut() = Some(ThreadInfo{
         stack_bounds: stack_bounds,
         stack_guard: stack_guard,
-        unwinding: false,
         thread: thread,
     }));
 }
diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs
index 6c6c0ce85eb..8ef53a22aeb 100644
--- a/src/libstd/thread.rs
+++ b/src/libstd/thread.rs
@@ -327,7 +327,7 @@ impl Thread {
 
     /// Determines whether the current thread is panicking.
     pub fn panicking() -> bool {
-        thread_info::panicking()
+        unwind::panicking()
     }
 
     /// Block unless or until the current thread's token is made available (may wake spuriously).