From d08600b189eeb2e61879b44a07f9fdc33fa82689 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 17 Dec 2014 14:59:20 -0800 Subject: 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. --- src/libstd/rt/unwind.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src/libstd/rt') 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 = 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: F) -> Result<(), Box> { let mut f = Some(f); + + let prev = PANICKING.with(|s| s.get()); + PANICKING.with(|s| s.set(false)); let ep = rust_try(try_fn::, &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: F) -> Result<(), Box> { } } +/// 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, 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); } -- cgit 1.4.1-3-g733a5