1use std::fmt::{self, Debug};
2
3use self::thread_id::ThreadId;
4
5pub struct ThreadBound<T> {
9 value: T,
10 thread_id: ThreadId,
11}
12
13unsafe impl<T> Sync for ThreadBound<T> {}
14
15unsafe impl<T: Copy> Send for ThreadBound<T> {}
17
18impl<T> ThreadBound<T> {
19 pub fn new(value: T) -> Self {
20 ThreadBound {
21 value: value,
22 thread_id: thread_id::current(),
23 }
24 }
25
26 pub fn get(&self) -> Option<&T> {
27 if thread_id::current() == self.thread_id {
28 Some(&self.value)
29 } else {
30 None
31 }
32 }
33}
34
35impl<T: Debug> Debug for ThreadBound<T> {
36 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
37 match self.get() {
38 Some(value) => Debug::fmt(value, formatter),
39 None => formatter.write_str("unknown"),
40 }
41 }
42}
43
44#[cfg(syn_can_use_thread_id)]
45mod thread_id {
46 use std::thread;
47
48 pub use std::thread::ThreadId;
49
50 pub fn current() -> ThreadId {
51 thread::current().id()
52 }
53}
54
55#[cfg(not(syn_can_use_thread_id))]
56mod thread_id {
57 #[allow(deprecated)]
58 use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
59
60 thread_local! {
61 static THREAD_ID: usize = {
62 #[allow(deprecated)]
63 static NEXT_THREAD_ID: AtomicUsize = ATOMIC_USIZE_INIT;
64
65 NEXT_THREAD_ID.fetch_add(1, Ordering::Relaxed)
75 };
76 }
77
78 pub type ThreadId = usize;
79
80 pub fn current() -> ThreadId {
81 THREAD_ID.with(|id| *id)
82 }
83}