1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#![allow(dead_code)]
use core::prelude::*;
use cell::RefCell;
use string::String;
use thread::Thread;
use thread::LocalKeyState;
struct ThreadInfo {
stack_guard: usize,
thread: Thread,
}
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 {
if THREAD_INFO.state() == LocalKeyState::Destroyed {
panic!("Use of std::thread::current() is not possible after \
the thread's local data has been destroyed");
}
THREAD_INFO.with(move |c| {
if c.borrow().is_none() {
*c.borrow_mut() = Some(ThreadInfo {
stack_guard: 0,
thread: NewThread::new(None),
})
}
f(c.borrow_mut().as_mut().unwrap())
})
}
}
pub fn current_thread() -> Thread {
ThreadInfo::with(|info| info.thread.clone())
}
pub fn stack_guard() -> usize {
ThreadInfo::with(|info| info.stack_guard)
}
pub fn set(stack_guard: usize, thread: Thread) {
THREAD_INFO.with(|c| assert!(c.borrow().is_none()));
THREAD_INFO.with(move |c| *c.borrow_mut() = Some(ThreadInfo{
stack_guard: stack_guard,
thread: thread,
}));
}
pub trait NewThread {
fn new(name: Option<String>) -> Self;
}