]> git.lizzy.rs Git - rust.git/blob - src/librustrt/local.rs
Add a few more derivings to AST types
[rust.git] / src / librustrt / local.rs
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use core::prelude::*;
12
13 use alloc::boxed::Box;
14 use local_ptr;
15 use task::Task;
16
17 /// Encapsulates some task-local data.
18 pub trait Local<Borrowed> {
19     fn put(value: Box<Self>);
20     fn take() -> Box<Self>;
21     fn try_take() -> Option<Box<Self>>;
22     fn exists(unused_value: Option<Self>) -> bool;
23     fn borrow(unused_value: Option<Self>) -> Borrowed;
24     unsafe fn unsafe_take() -> Box<Self>;
25     unsafe fn unsafe_borrow() -> *mut Self;
26     unsafe fn try_unsafe_borrow() -> Option<*mut Self>;
27 }
28
29 #[allow(visible_private_types)]
30 impl Local<local_ptr::Borrowed<Task>> for Task {
31     #[inline]
32     fn put(value: Box<Task>) { unsafe { local_ptr::put(value) } }
33     #[inline]
34     fn take() -> Box<Task> { unsafe { local_ptr::take() } }
35     #[inline]
36     fn try_take() -> Option<Box<Task>> { unsafe { local_ptr::try_take() } }
37     fn exists(_: Option<Task>) -> bool { local_ptr::exists() }
38     #[inline]
39     fn borrow(_: Option<Task>) -> local_ptr::Borrowed<Task> {
40         unsafe {
41             local_ptr::borrow::<Task>()
42         }
43     }
44     #[inline]
45     unsafe fn unsafe_take() -> Box<Task> { local_ptr::unsafe_take() }
46     #[inline]
47     unsafe fn unsafe_borrow() -> *mut Task { local_ptr::unsafe_borrow() }
48     #[inline]
49     unsafe fn try_unsafe_borrow() -> Option<*mut Task> {
50         local_ptr::try_unsafe_borrow()
51     }
52 }
53
54 #[cfg(test)]
55 mod test {
56     use std::prelude::*;
57     use std::rt::thread::Thread;
58     use super::*;
59     use task::Task;
60
61     #[test]
62     fn thread_local_task_smoke_test() {
63         Thread::start(proc() {
64             let task = box Task::new();
65             Local::put(task);
66             let task: Box<Task> = Local::take();
67             cleanup_task(task);
68         }).join();
69     }
70
71     #[test]
72     fn thread_local_task_two_instances() {
73         Thread::start(proc() {
74             let task = box Task::new();
75             Local::put(task);
76             let task: Box<Task> = Local::take();
77             cleanup_task(task);
78             let task = box Task::new();
79             Local::put(task);
80             let task: Box<Task> = Local::take();
81             cleanup_task(task);
82         }).join();
83     }
84
85     #[test]
86     fn borrow_smoke_test() {
87         Thread::start(proc() {
88             let task = box Task::new();
89             Local::put(task);
90
91             unsafe {
92                 let _task: *mut Task = Local::unsafe_borrow();
93             }
94             let task: Box<Task> = Local::take();
95             cleanup_task(task);
96         }).join();
97     }
98
99     #[test]
100     fn borrow_with_return() {
101         Thread::start(proc() {
102             let task = box Task::new();
103             Local::put(task);
104
105             {
106                 let _ = Local::borrow(None::<Task>);
107             }
108
109             let task: Box<Task> = Local::take();
110             cleanup_task(task);
111         }).join();
112     }
113
114     #[test]
115     fn try_take() {
116         Thread::start(proc() {
117             let task = box Task::new();
118             Local::put(task);
119
120             let t: Box<Task> = Local::try_take().unwrap();
121             let u: Option<Box<Task>> = Local::try_take();
122             assert!(u.is_none());
123
124             cleanup_task(t);
125         }).join();
126     }
127
128     fn cleanup_task(mut t: Box<Task>) {
129         t.destroyed = true;
130     }
131
132 }