diff options
Diffstat (limited to 'src/libstd/task')
| -rw-r--r-- | src/libstd/task/mod.rs | 39 | ||||
| -rw-r--r-- | src/libstd/task/spawn.rs | 38 |
2 files changed, 56 insertions, 21 deletions
diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs index a8e8cfd163a..5a3ff10ae83 100644 --- a/src/libstd/task/mod.rs +++ b/src/libstd/task/mod.rs @@ -497,11 +497,26 @@ pub fn try<T:Send>(f: ~fn() -> T) -> Result<T,()> { pub fn yield() { //! Yield control to the task scheduler + use rt::{context, OldTaskContext}; + use rt::local::Local; + use rt::sched::Scheduler; + unsafe { - let task_ = rt::rust_get_task(); - let killed = rt::rust_task_yield(task_); - if killed && !failing() { - fail!("killed"); + match context() { + OldTaskContext => { + let task_ = rt::rust_get_task(); + let killed = rt::rust_task_yield(task_); + if killed && !failing() { + fail!("killed"); + } + } + _ => { + // XXX: What does yield really mean in newsched? + let sched = Local::take::<Scheduler>(); + do sched.deschedule_running_task_and_then |sched, task| { + sched.enqueue_task(task); + } + } } } } @@ -520,20 +535,9 @@ pub fn failing() -> bool { } } _ => { - let mut unwinding = false; - do Local::borrow::<Task> |local| { - unwinding = match local.unwinder { - Some(unwinder) => { - unwinder.unwinding - } - None => { - // Because there is no unwinder we can't be unwinding. - // (The process will abort on failure) - false - } - } + do Local::borrow::<Task, bool> |local| { + local.unwinder.unwinding } - return unwinding; } } } @@ -1191,3 +1195,4 @@ fn test_simple_newsched_spawn() { spawn(||()) } } + diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 190485a720a..bcb7e06bf1f 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -91,6 +91,7 @@ use uint; use util; use unstable::sync::{Exclusive, exclusive}; use rt::local::Local; +use rt::task::Task; use iterator::IteratorUtil; #[cfg(test)] use task::default_task_opts; @@ -581,12 +582,41 @@ pub fn spawn_raw(opts: TaskOpts, f: ~fn()) { } } -fn spawn_raw_newsched(_opts: TaskOpts, f: ~fn()) { +fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) { use rt::sched::*; - let mut sched = Local::take::<Scheduler>(); - let task = ~Coroutine::new(&mut sched.stack_pool, f); - sched.schedule_new_task(task); + let f = Cell::new(f); + + let mut task = unsafe { + let sched = Local::unsafe_borrow::<Scheduler>(); + rtdebug!("unsafe borrowed sched"); + + if opts.linked { + do Local::borrow::<Task, ~Task>() |running_task| { + ~running_task.new_child(&mut (*sched).stack_pool, f.take()) + } + } else { + // An unlinked task is a new root in the task tree + ~Task::new_root(&mut (*sched).stack_pool, f.take()) + } + }; + + if opts.notify_chan.is_some() { + let notify_chan = opts.notify_chan.swap_unwrap(); + let notify_chan = Cell::new(notify_chan); + let on_exit: ~fn(bool) = |success| { + notify_chan.take().send( + if success { Success } else { Failure } + ) + }; + task.on_exit = Some(on_exit); + } + + rtdebug!("spawn about to take scheduler"); + + let sched = Local::take::<Scheduler>(); + rtdebug!("took sched in spawn"); + sched.schedule_task(task); } fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { |
