Skip to content

Commit 16652c9

Browse files
committed
auto merge of #5909 : brson/rust/rt4, r=graydon
This is just a bunch of minor changes and simplifications to the structure of core::rt. It makes ownership of the ~Scheduler more strict (though it is still mutably aliased sometimes), turns the scheduler cleanup_jobs vector into just a single job, shunts the thread-local scheduler code off to its own file.
2 parents a089c6f + 7bfd0e5 commit 16652c9

File tree

4 files changed

+457
-449
lines changed

4 files changed

+457
-449
lines changed

src/libcore/rt/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ macro_rules! rtdebug (
3232
($( $arg:expr),+) => ( $(let _ = $arg)*; )
3333
)
3434

35+
#[path = "sched/mod.rs"]
3536
mod sched;
3637
mod rtio;
3738
pub mod uvll;

src/libcore/rt/sched/local.rs

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
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+
//! Access to the thread-local Scheduler
12+
13+
use ptr::mut_null;
14+
use libc::c_void;
15+
use cast::transmute;
16+
17+
use super::Scheduler;
18+
use tls = super::super::thread_local_storage;
19+
#[cfg(test)] use super::super::uvio::UvEventLoop;
20+
21+
/// Give the Scheduler to thread-local storage
22+
pub fn put(sched: ~Scheduler) {
23+
unsafe {
24+
let key = tls_key();
25+
let void_sched: *mut c_void = transmute::<~Scheduler, *mut c_void>(sched);
26+
tls::set(key, void_sched);
27+
}
28+
}
29+
30+
/// Take ownership of the Scheduler from thread-local storage
31+
pub fn take() -> ~Scheduler {
32+
unsafe {
33+
let key = tls_key();
34+
let void_sched: *mut c_void = tls::get(key);
35+
assert!(void_sched.is_not_null());
36+
let sched = transmute::<*mut c_void, ~Scheduler>(void_sched);
37+
tls::set(key, mut_null());
38+
return sched;
39+
}
40+
}
41+
42+
/// Borrow a mutable reference to the thread-local Scheduler
43+
/// # Safety Note
44+
/// Because this leaves the Scheduler in thread-local storage it is possible
45+
/// For the Scheduler pointer to be aliased
46+
pub unsafe fn borrow() -> &mut Scheduler {
47+
unsafe {
48+
let key = tls_key();
49+
let mut void_sched: *mut c_void = tls::get(key);
50+
assert!(void_sched.is_not_null());
51+
{
52+
let void_sched_ptr = &mut void_sched;
53+
let sched: &mut ~Scheduler = {
54+
transmute::<&mut *mut c_void, &mut ~Scheduler>(void_sched_ptr)
55+
};
56+
let sched: &mut Scheduler = &mut **sched;
57+
return sched;
58+
}
59+
}
60+
}
61+
62+
fn tls_key() -> tls::Key {
63+
unsafe {
64+
let key: *mut c_void = rust_get_sched_tls_key();
65+
let key: &mut tls::Key = transmute(key);
66+
return *key;
67+
}
68+
}
69+
70+
extern {
71+
fn rust_get_sched_tls_key() -> *mut c_void;
72+
}
73+
74+
#[test]
75+
fn thread_local_scheduler_smoke_test() {
76+
let scheduler = ~UvEventLoop::new_scheduler();
77+
put(scheduler);
78+
let _scheduler = take();
79+
}
80+
81+
#[test]
82+
fn thread_local_scheduler_two_instances() {
83+
let scheduler = ~UvEventLoop::new_scheduler();
84+
put(scheduler);
85+
let _scheduler = take();
86+
let scheduler = ~UvEventLoop::new_scheduler();
87+
put(scheduler);
88+
let _scheduler = take();
89+
}
90+
91+
#[test]
92+
fn borrow_smoke_test() {
93+
let scheduler = ~UvEventLoop::new_scheduler();
94+
put(scheduler);
95+
unsafe {
96+
let _scheduler = borrow();
97+
}
98+
let _scheduler = take();
99+
}
100+

0 commit comments

Comments
 (0)