(index<- ) ./libstd/rt/local.rs
git branch: * master 5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
modified: Fri May 9 13:02:28 2014
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 option::Option;
12 use owned::Box;
13 use rt::task::Task;
14 use rt::local_ptr;
15
16 /// Encapsulates some task-local data.
17 pub trait Local<Borrowed> {
18 fn put(value: Box<Self>);
19 fn take() -> Box<Self>;
20 fn try_take() -> Option<Box<Self>>;
21 fn exists(unused_value: Option<Self>) -> bool;
22 fn borrow(unused_value: Option<Self>) -> Borrowed;
23 unsafe fn unsafe_take() -> Box<Self>;
24 unsafe fn unsafe_borrow() -> *mut Self;
25 unsafe fn try_unsafe_borrow() -> Option<*mut Self>;
26 }
27
28 #[allow(visible_private_types)]
29 impl Local<local_ptr::Borrowed<Task>> for Task {
30 #[inline]
31 fn put(value: Box<Task>) { unsafe { local_ptr::put(value) } }
32 #[inline]
33 fn take() -> Box<Task> { unsafe { local_ptr::take() } }
34 #[inline]
35 fn try_take() -> Option<Box<Task>> { unsafe { local_ptr::try_take() } }
36 fn exists(_: Option<Task>) -> bool { local_ptr::exists() }
37 #[inline]
38 fn borrow(_: Option<Task>) -> local_ptr::Borrowed<Task> {
39 unsafe {
40 local_ptr::borrow::<Task>()
41 }
42 }
43 #[inline]
44 unsafe fn unsafe_take() -> Box<Task> { local_ptr::unsafe_take() }
45 #[inline]
46 unsafe fn unsafe_borrow() -> *mut Task { local_ptr::unsafe_borrow() }
47 #[inline]
48 unsafe fn try_unsafe_borrow() -> Option<*mut Task> {
49 local_ptr::try_unsafe_borrow()
50 }
51 }
52
53 #[cfg(test)]
54 mod test {
55 use option::{None, Option};
56 use unstable::run_in_bare_thread;
57 use super::*;
58 use owned::Box;
59 use rt::task::Task;
60
61 #[test]
62 fn thread_local_task_smoke_test() {
63 run_in_bare_thread(proc() {
64 let task = box Task::new();
65 Local::put(task);
66 let task: Box<Task> = Local::take();
67 cleanup_task(task);
68 });
69 }
70
71 #[test]
72 fn thread_local_task_two_instances() {
73 run_in_bare_thread(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 });
83 }
84
85 #[test]
86 fn borrow_smoke_test() {
87 run_in_bare_thread(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 });
97 }
98
99 #[test]
100 fn borrow_with_return() {
101 run_in_bare_thread(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 });
112 }
113
114 #[test]
115 fn try_take() {
116 run_in_bare_thread(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 });
126 }
127
128 fn cleanup_task(mut t: Box<Task>) {
129 t.destroyed = true;
130 }
131
132 }