about summary refs log tree commit diff
path: root/src/libstd/task
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/task')
-rw-r--r--src/libstd/task/mod.rs39
-rw-r--r--src/libstd/task/spawn.rs38
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()) {