Skip to content

Commit d08600b

Browse files
alexcrichtonaturon
authored andcommitted
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.
1 parent 5759cff commit d08600b

File tree

4 files changed

+21
-27
lines changed

4 files changed

+21
-27
lines changed

src/libstd/failure.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,15 @@
1010

1111
#![experimental]
1212

13-
use alloc::boxed::Box;
13+
use prelude::*;
14+
1415
use any::{Any, AnyRefExt};
1516
use cell::RefCell;
1617
use fmt;
17-
use io::{Writer, IoResult};
18-
use kinds::Send;
19-
use option::Option;
20-
use option::Option::{Some, None};
21-
use result::Result::Ok;
22-
use rt::backtrace;
18+
use io::IoResult;
19+
use rt::{backtrace, unwind};
2320
use rt::util::{Stderr, Stdio};
24-
use str::Str;
25-
use string::String;
2621
use thread::Thread;
27-
use sys_common::thread_info;
2822

2923
// Defined in this module instead of io::stdio so that the unwinding
3024
thread_local! {
@@ -80,7 +74,7 @@ pub fn on_fail(obj: &(Any+Send), file: &'static str, line: uint) {
8074

8175
// If this is a double panic, make sure that we printed a backtrace
8276
// for this panic.
83-
if thread_info::panicking() && !backtrace::log_enabled() {
77+
if unwind::panicking() && !backtrace::log_enabled() {
8478
let _ = backtrace::write(&mut err);
8579
}
8680
}

src/libstd/rt/unwind.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
use prelude::*;
6161

6262
use any::Any;
63+
use cell::Cell;
6364
use cmp;
6465
use failure;
6566
use fmt;
@@ -69,7 +70,6 @@ use mem;
6970
use sync::atomic;
7071
use sync::{Once, ONCE_INIT};
7172

72-
use sys_common::thread_info;
7373
use rt::libunwind as uw;
7474

7575
struct Exception {
@@ -94,6 +94,8 @@ static CALLBACKS: [atomic::AtomicUint, ..MAX_CALLBACKS] =
9494
atomic::INIT_ATOMIC_UINT, atomic::INIT_ATOMIC_UINT];
9595
static CALLBACK_CNT: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
9696

97+
thread_local!(static PANICKING: Cell<bool> = Cell::new(false))
98+
9799
/// Invoke a closure, capturing the cause of panic if one occurs.
98100
///
99101
/// 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;
116118
/// run.
117119
pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
118120
let mut f = Some(f);
121+
122+
let prev = PANICKING.with(|s| s.get());
123+
PANICKING.with(|s| s.set(false));
119124
let ep = rust_try(try_fn::<F>, &mut f as *mut _ as *mut c_void);
125+
PANICKING.with(|s| s.set(prev));
120126
return if ep.is_null() {
121127
Ok(())
122128
} else {
@@ -146,6 +152,11 @@ pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
146152
}
147153
}
148154

155+
/// Test if the current thread is currently panicking.
156+
pub fn panicking() -> bool {
157+
PANICKING.with(|s| s.get())
158+
}
159+
149160
// An uninlined, unmangled function upon which to slap yer breakpoints
150161
#[inline(never)]
151162
#[no_mangle]
@@ -561,15 +572,15 @@ fn begin_unwind_inner(msg: Box<Any + Send>, file_line: &(&'static str, uint)) ->
561572

562573
// Now that we've run all the necessary unwind callbacks, we actually
563574
// perform the unwinding.
564-
if thread_info::panicking() {
575+
if panicking() {
565576
// If a thread panics while it's already unwinding then we
566577
// have limited options. Currently our preference is to
567578
// just abort. In the future we may consider resuming
568579
// unwinding or otherwise exiting the task cleanly.
569-
rterrln!("task failed during unwinding. aborting.");
580+
rterrln!("thread panicked while panicking. aborting.");
570581
unsafe { intrinsics::abort() }
571582
}
572-
thread_info::set_unwinding(true);
583+
PANICKING.with(|s| s.set(true));
573584
rust_panic(msg);
574585
}
575586

src/libstd/sys/common/thread_info.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ struct ThreadInfo {
2020
// hence this is optional.
2121
stack_bounds: (uint, uint),
2222
stack_guard: uint,
23-
unwinding: bool,
2423
thread: Thread,
2524
}
2625

@@ -38,7 +37,6 @@ impl ThreadInfo {
3837
*c.borrow_mut() = Some(ThreadInfo {
3938
stack_bounds: (0, 0),
4039
stack_guard: 0,
41-
unwinding: false,
4240
thread: NewThread::new(None),
4341
})
4442
}
@@ -51,24 +49,15 @@ pub fn current_thread() -> Thread {
5149
ThreadInfo::with(|info| info.thread.clone())
5250
}
5351

54-
pub fn panicking() -> bool {
55-
ThreadInfo::with(|info| info.unwinding)
56-
}
57-
5852
pub fn stack_guard() -> uint {
5953
ThreadInfo::with(|info| info.stack_guard)
6054
}
6155

62-
pub fn set_unwinding(unwinding: bool) {
63-
ThreadInfo::with(|info| info.unwinding = unwinding)
64-
}
65-
6656
pub fn set(stack_bounds: (uint, uint), stack_guard: uint, thread: Thread) {
6757
THREAD_INFO.with(|c| assert!(c.borrow().is_none()));
6858
THREAD_INFO.with(move |c| *c.borrow_mut() = Some(ThreadInfo{
6959
stack_bounds: stack_bounds,
7060
stack_guard: stack_guard,
71-
unwinding: false,
7261
thread: thread,
7362
}));
7463
}

src/libstd/thread.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ impl Thread {
327327

328328
/// Determines whether the current thread is panicking.
329329
pub fn panicking() -> bool {
330-
thread_info::panicking()
330+
unwind::panicking()
331331
}
332332

333333
/// Block unless or until the current thread's token is made available (may wake spuriously).

0 commit comments

Comments
 (0)