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.
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.
11 use option::{Option, Some, None};
12 use rt::sched::Scheduler;
15 use rt::rtio::{EventLoop, IoFactoryObject};
16 //use borrow::to_uint;
23 fn borrow<T>(f: &fn(&mut Self) -> T) -> T;
24 unsafe fn unsafe_borrow() -> *mut Self;
25 unsafe fn try_unsafe_borrow() -> Option<*mut Self>;
29 fn put(value: ~Task) { unsafe { local_ptr::put(value) } }
30 fn take() -> ~Task { unsafe { local_ptr::take() } }
31 fn exists() -> bool { local_ptr::exists() }
32 fn borrow<T>(f: &fn(&mut Task) -> T) -> T {
33 let mut res: Option<T> = None;
34 let res_ptr: *mut Option<T> = &mut res;
36 do local_ptr::borrow |task| {
38 *res_ptr = Some(result);
43 None => { rtabort!("function failed in local_borrow") }
46 unsafe fn unsafe_borrow() -> *mut Task { local_ptr::unsafe_borrow() }
47 unsafe fn try_unsafe_borrow() -> Option<*mut Task> {
48 if Local::exists::<Task>() {
49 Some(Local::unsafe_borrow())
56 impl Local for Scheduler {
57 fn put(value: ~Scheduler) {
58 let value = Cell::new(value);
59 do Local::borrow::<Task,()> |task| {
61 task.sched = Some(value.take());
64 fn take() -> ~Scheduler {
65 do Local::borrow::<Task,~Scheduler> |task| {
66 let sched = task.sched.take_unwrap();
73 do Local::borrow::<Task,bool> |task| {
75 Some(ref _task) => true,
80 fn borrow<T>(f: &fn(&mut Scheduler) -> T) -> T {
81 do Local::borrow::<Task, T> |task| {
83 Some(~ref mut task) => {
87 rtabort!("no scheduler")
92 unsafe fn unsafe_borrow() -> *mut Scheduler {
93 match (*Local::unsafe_borrow::<Task>()).sched {
94 Some(~ref mut sched) => {
95 let s: *mut Scheduler = &mut *sched;
99 rtabort!("no scheduler")
103 unsafe fn try_unsafe_borrow() -> Option<*mut Scheduler> {
104 if Local::exists::<Scheduler>() {
105 Some(Local::unsafe_borrow())
112 // XXX: This formulation won't work once ~IoFactoryObject is a real trait pointer
113 impl Local for IoFactoryObject {
114 fn put(_value: ~IoFactoryObject) { rtabort!("unimpl") }
115 fn take() -> ~IoFactoryObject { rtabort!("unimpl") }
116 fn exists() -> bool { rtabort!("unimpl") }
117 fn borrow<T>(_f: &fn(&mut IoFactoryObject) -> T) -> T { rtabort!("unimpl") }
118 unsafe fn unsafe_borrow() -> *mut IoFactoryObject {
119 let sched = Local::unsafe_borrow::<Scheduler>();
120 let io: *mut IoFactoryObject = (*sched).event_loop.io().unwrap();
123 unsafe fn try_unsafe_borrow() -> Option<*mut IoFactoryObject> { rtabort!("unimpl") }
130 use unstable::run_in_bare_thread;
137 fn thread_local_task_smoke_test() {
138 do run_in_bare_thread {
139 local_ptr::init_tls_key();
140 let mut sched = ~new_test_uv_sched();
141 let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
143 let task: ~Task = Local::take();
149 fn thread_local_task_two_instances() {
150 do run_in_bare_thread {
151 local_ptr::init_tls_key();
152 let mut sched = ~new_test_uv_sched();
153 let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
155 let task: ~Task = Local::take();
157 let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
159 let task: ~Task = Local::take();
166 fn borrow_smoke_test() {
167 do run_in_bare_thread {
168 local_ptr::init_tls_key();
169 let mut sched = ~new_test_uv_sched();
170 let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
174 let _task: *mut Task = Local::unsafe_borrow();
176 let task: ~Task = Local::take();
182 fn borrow_with_return() {
183 do run_in_bare_thread {
184 local_ptr::init_tls_key();
185 let mut sched = ~new_test_uv_sched();
186 let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
189 let res = do Local::borrow::<Task,bool> |_task| {
193 let task: ~Task = Local::take();