use cell::RefCell;
use rt::{backtrace, unwind};
use sys::stdio::Stderr;
-use thread;
+use sys_common::thread_info;
thread_local! {
pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
}
};
let mut err = Stderr::new();
- let thread = thread::current();
- let name = thread.name().unwrap_or("<unnamed>");
+ let thread = thread_info::current_thread();
+ let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
let prev = LOCAL_STDERR.with(|s| s.borrow_mut().take());
match prev {
Some(mut stderr) => {
thread_local! { static THREAD_INFO: RefCell<Option<ThreadInfo>> = RefCell::new(None) }
impl ThreadInfo {
- fn with<R, F>(f: F) -> R where F: FnOnce(&mut ThreadInfo) -> R {
+ fn with<R, F>(f: F) -> Option<R> where F: FnOnce(&mut ThreadInfo) -> R {
if THREAD_INFO.state() == LocalKeyState::Destroyed {
- panic!("Use of std::thread::current() is not possible after \
- the thread's local data has been destroyed");
+ return None
}
THREAD_INFO.with(move |c| {
thread: NewThread::new(None),
})
}
- f(c.borrow_mut().as_mut().unwrap())
+ Some(f(c.borrow_mut().as_mut().unwrap()))
})
}
}
-pub fn current_thread() -> Thread {
+pub fn current_thread() -> Option<Thread> {
ThreadInfo::with(|info| info.thread.clone())
}
-pub fn stack_guard() -> usize {
+pub fn stack_guard() -> Option<usize> {
ThreadInfo::with(|info| info.stack_guard)
}
// We're calling into functions with stack checks
stack::record_sp_limit(0);
- let guard = thread_info::stack_guard();
+ let guard = thread_info::stack_guard().unwrap_or(0);
let addr = (*info).si_addr as usize;
if guard == 0 || addr < guard - PAGE_SIZE || addr >= guard {
/// Gets a handle to the thread that invokes it.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn current() -> Thread {
- thread_info::current_thread()
+ thread_info::current_thread().expect("use of std::thread::current() is not \
+ possible after the thread's local \
+ data has been destroyed")
}
/// Cooperatively gives up a timeslice to the OS scheduler.
--- /dev/null
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::thread;
+use std::env;
+use std::process::Command;
+
+struct Handle(i32);
+
+impl Drop for Handle {
+ fn drop(&mut self) { panic!(); }
+}
+
+thread_local!(static HANDLE: Handle = Handle(0));
+
+fn main() {
+ let args = env::args().collect::<Vec<_>>();
+ if args.len() == 1 {
+ let out = Command::new(&args[0]).arg("test").output().unwrap();
+ let stderr = std::str::from_utf8(&out.stderr).unwrap();
+ assert!(stderr.contains("panicked at 'explicit panic'"),
+ "bad failure message:\n{}\n", stderr);
+ } else {
+ // TLS dtors are not always run on process exit
+ thread::spawn(|| {
+ HANDLE.with(|h| {
+ println!("{}", h.0);
+ });
+ }).join().unwrap();
+ }
+}
+