提交 20426962 编写于 作者: B Brian Anderson

core::rt: Implement Local for Task

上级 2f99fb8e
......@@ -66,8 +66,11 @@ pub fn log_type<T>(level: u32, object: &T) {
}
fn newsched_log_str(msg: ~str) {
use rt::task::Task;
use rt::local::Local;
unsafe {
match rt::task::unsafe_try_borrow_local_task() {
match Local::try_unsafe_borrow::<Task>() {
Some(local) => {
// Use the available logger
(*local).logger.log(Left(msg));
......
......@@ -8,7 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use option::{Option, Some, None};
use rt::sched::Scheduler;
use rt::task::Task;
use rt::local_ptr;
pub trait Local {
......@@ -17,6 +19,7 @@ pub trait Local {
fn exists() -> bool;
fn borrow(f: &fn(&mut Self));
unsafe fn unsafe_borrow() -> *mut Self;
unsafe fn try_unsafe_borrow() -> Option<*mut Self>;
}
impl Local for Scheduler {
......@@ -25,6 +28,44 @@ fn take() -> ~Scheduler { unsafe { local_ptr::take() } }
fn exists() -> bool { local_ptr::exists() }
fn borrow(f: &fn(&mut Scheduler)) { unsafe { local_ptr::borrow(f) } }
unsafe fn unsafe_borrow() -> *mut Scheduler { local_ptr::unsafe_borrow() }
unsafe fn try_unsafe_borrow() -> Option<*mut Scheduler> { abort!("unimpl") }
}
impl Local for Task {
fn put(value: ~Task) { abort!("unimpl") }
fn take() -> ~Task { abort!("unimpl") }
fn exists() -> bool { abort!("unimpl") }
fn borrow(f: &fn(&mut Task)) {
do Local::borrow::<Scheduler> |sched| {
match sched.current_task {
Some(~ref mut task) => {
f(&mut *task.task)
}
None => {
abort!("no scheduler")
}
}
}
}
unsafe fn unsafe_borrow() -> *mut Task {
match (*Local::unsafe_borrow::<Scheduler>()).current_task {
Some(~ref mut task) => {
let s: *mut Task = &mut *task.task;
return s;
}
None => {
// Don't fail. Infinite recursion
abort!("no scheduler")
}
}
}
unsafe fn try_unsafe_borrow() -> Option<*mut Task> {
if Local::exists::<Scheduler>() {
Some(Local::unsafe_borrow())
} else {
None
}
}
}
#[cfg(test)]
......
......@@ -63,7 +63,7 @@ pub fn without_unwinding() -> Task {
pub fn run(&mut self, f: &fn()) {
// This is just an assertion that `run` was called unsafely
// and this instance of Task is still accessible.
do borrow_local_task |task| {
do Local::borrow::<Task> |task| {
assert!(ptr::ref_eq(task, self));
}
......@@ -88,7 +88,7 @@ pub fn run(&mut self, f: &fn()) {
fn destroy(&mut self) {
// This is just an assertion that `destroy` was called unsafely
// and this instance of Task is still accessible.
do borrow_local_task |task| {
do Local::borrow::<Task> |task| {
assert!(ptr::ref_eq(task, self));
}
match self.storage {
......@@ -150,42 +150,6 @@ pub fn begin_unwind(&mut self) -> ! {
}
}
/// Borrow a pointer to the installed local services.
/// Fails (likely aborting the process) if local services are not available.
pub fn borrow_local_task(f: &fn(&mut Task)) {
do Local::borrow::<Scheduler> |sched| {
match sched.current_task {
Some(~ref mut task) => {
f(&mut *task.task)
}
None => {
fail!("no local services for schedulers yet")
}
}
}
}
pub unsafe fn unsafe_borrow_local_task() -> *mut Task {
match (*Local::unsafe_borrow::<Scheduler>()).current_task {
Some(~ref mut task) => {
let s: *mut Task = &mut *task.task;
return s;
}
None => {
// Don't fail. Infinite recursion
abort!("no local services for schedulers yet")
}
}
}
pub unsafe fn unsafe_try_borrow_local_task() -> Option<*mut Task> {
if Local::exists::<Scheduler>() {
Some(unsafe_borrow_local_task())
} else {
None
}
}
#[cfg(test)]
mod test {
use rt::test::*;
......
......@@ -204,7 +204,8 @@ fn fail_with(cause: &'static str, file: &'static str, line: uint) -> ! {
pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
use option::Option;
use rt::{context, OldTaskContext, TaskContext};
use rt::task::{unsafe_borrow_local_task, Unwinder};
use rt::task::{Task, Unwinder};
use rt::local::Local;
let context = context();
match context {
......@@ -233,7 +234,7 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! {
gc::cleanup_stack_for_failure();
let task = unsafe_borrow_local_task();
let task = Local::unsafe_borrow::<Task>();
let unwinder: &mut Option<Unwinder> = &mut (*task).unwinder;
match *unwinder {
Some(ref mut unwinder) => unwinder.begin_unwind(),
......
......@@ -18,7 +18,7 @@
use local_data::LocalDataKey;
use super::rt::rust_task;
use rt::task::LocalStorage;
use rt::task::{Task, LocalStorage};
pub enum Handle {
OldHandle(*rust_task),
......@@ -28,14 +28,14 @@ pub enum Handle {
impl Handle {
pub fn new() -> Handle {
use rt::{context, OldTaskContext};
use rt::task::unsafe_borrow_local_task;
use rt::local::Local;
unsafe {
match context() {
OldTaskContext => {
OldHandle(rt::rust_get_task())
}
_ => {
let task = unsafe_borrow_local_task();
let task = Local::unsafe_borrow::<Task>();
NewHandle(&mut (*task).storage)
}
}
......
......@@ -504,7 +504,8 @@ pub fn failing() -> bool {
//! True if the running task has failed
use rt::{context, OldTaskContext};
use rt::task::borrow_local_task;
use rt::local::Local;
use rt::task::Task;
match context() {
OldTaskContext => {
......@@ -514,7 +515,7 @@ pub fn failing() -> bool {
}
_ => {
let mut unwinding = false;
do borrow_local_task |local| {
do Local::borrow::<Task> |local| {
unwinding = match local.unwinder {
Some(unwinder) => {
unwinder.unwinding
......
......@@ -17,7 +17,8 @@
use str;
use sys;
use rt::{context, OldTaskContext};
use rt::task::borrow_local_task;
use rt::task::Task;
use rt::local::Local;
use option::{Option, Some, None};
use io;
use rt::global_heap;
......@@ -243,7 +244,7 @@ pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
}
_ => {
let mut alloc = ::ptr::null();
do borrow_local_task |task| {
do Local::borrow::<Task> |task| {
alloc = task.heap.alloc(td as *c_void, size as uint) as *c_char;
}
return alloc;
......@@ -261,7 +262,7 @@ pub unsafe fn local_free(ptr: *c_char) {
rustrt::rust_upcall_free_noswitch(ptr);
}
_ => {
do borrow_local_task |task| {
do Local::borrow::<Task> |task| {
task.heap.free(ptr as *c_void);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册