blob: 2c15912ff397a4588d45a877ea73f569bf1e8547 [file] [log] [blame]
David Tolnay32874802018-11-11 08:52:19 -08001use std::fmt::{self, Debug};
2
3#[cfg(syn_can_use_thread_id)]
4mod imp {
5 use std::thread::{self, ThreadId};
6
7 /// ThreadBound is a Sync-maker and Send-maker that allows accessing a value
8 /// of type T only from the original thread on which the ThreadBound was
9 /// constructed.
10 pub struct ThreadBound<T> {
11 value: T,
12 thread_id: ThreadId,
13 }
14
15 unsafe impl<T> Sync for ThreadBound<T> {}
16
17 // Send bound requires Copy, as otherwise Drop could run in the wrong place.
18 unsafe impl<T: Copy> Send for ThreadBound<T> {}
19
20 impl<T> ThreadBound<T> {
21 pub fn new(value: T) -> Self {
22 ThreadBound {
23 value: value,
24 thread_id: thread::current().id(),
25 }
26 }
27
28 pub fn get(&self) -> Option<&T> {
29 if thread::current().id() == self.thread_id {
30 Some(&self.value)
31 } else {
32 None
33 }
34 }
35 }
36}
37
38#[cfg(not(syn_can_use_thread_id))]
39mod imp {
40 pub struct ThreadBound<T> {
41 value: T,
42 }
43
44 impl<T> ThreadBound<T> {
45 pub fn new(value: T) -> Self {
46 ThreadBound {
47 value: value,
48 }
49 }
50
51 pub fn get(&self) -> Option<&T> {
52 Some(&self.value)
53 }
54 }
55}
56
57pub use self::imp::ThreadBound;
58
59impl<T: Debug> Debug for ThreadBound<T> {
60 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
61 match self.get() {
62 Some(value) => Debug::fmt(value, formatter),
63 None => formatter.write_str("unknown"),
64 }
65 }
66}