core::rt: Implement Local for Task
This commit is contained in:
parent
2f99fb8efa
commit
2042696236
src/libcore
@ -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 @@ impl Local for Scheduler {
|
||||
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 @@ impl 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 @@ impl Task {
|
||||
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 @@ impl Unwinder {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 @@ impl FailWithCause for &'static str {
|
||||
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 task::rt;
|
||||
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 managed::raw::BoxRepr;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user