about summary refs log tree commit diff
path: root/src/libstd/rt/task.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/rt/task.rs')
-rw-r--r--src/libstd/rt/task.rs111
1 files changed, 54 insertions, 57 deletions
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index 63cc397e8d7..86cc895eb27 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -19,7 +19,6 @@ use prelude::*;
 
 use borrow;
 use cast::transmute;
-use cell::Cell;
 use cleanup;
 use libc::{c_void, uintptr_t, c_char, size_t};
 use local_data;
@@ -144,17 +143,15 @@ impl Task {
                              f: proc(),
                              home: SchedHome)
                              -> ~Task {
-        let f = Cell::new(f);
-        let home = Cell::new(home);
-        Local::borrow(|running_task: &mut Task| {
-            let mut sched = running_task.sched.take_unwrap();
-            let new_task = ~running_task.new_child_homed(&mut sched.stack_pool,
-                                                         stack_size,
-                                                         home.take(),
-                                                         f.take());
-            running_task.sched = Some(sched);
-            new_task
-        })
+        let mut running_task = Local::borrow(None::<Task>);
+        let mut sched = running_task.get().sched.take_unwrap();
+        let new_task = ~running_task.get()
+                                    .new_child_homed(&mut sched.stack_pool,
+                                                     stack_size,
+                                                     home,
+                                                     f);
+        running_task.get().sched = Some(sched);
+        new_task
     }
 
     pub fn build_child(stack_size: Option<uint>, f: proc()) -> ~Task {
@@ -165,17 +162,14 @@ impl Task {
                             f: proc(),
                             home: SchedHome)
                             -> ~Task {
-        let f = Cell::new(f);
-        let home = Cell::new(home);
-        Local::borrow(|running_task: &mut Task| {
-            let mut sched = running_task.sched.take_unwrap();
-            let new_task = ~Task::new_root_homed(&mut sched.stack_pool,
-                                                 stack_size,
-                                                 home.take(),
-                                                 f.take());
-            running_task.sched = Some(sched);
-            new_task
-        })
+        let mut running_task = Local::borrow(None::<Task>);
+        let mut sched = running_task.get().sched.take_unwrap();
+        let new_task = ~Task::new_root_homed(&mut sched.stack_pool,
+                                             stack_size,
+                                             home,
+                                             f);
+        running_task.get().sched = Some(sched);
+        new_task
     }
 
     pub fn build_root(stack_size: Option<uint>, f: proc()) -> ~Task {
@@ -371,26 +365,25 @@ impl Task {
     // Grab both the scheduler and the task from TLS and check if the
     // task is executing on an appropriate scheduler.
     pub fn on_appropriate_sched() -> bool {
-        Local::borrow(|task: &mut Task| {
-            let sched_id = task.sched.get_ref().sched_id();
-            let sched_run_anything = task.sched.get_ref().run_anything;
-            match task.task_type {
-                GreenTask(Some(AnySched)) => {
-                    rtdebug!("anysched task in sched check ****");
-                    sched_run_anything
-                }
-                GreenTask(Some(Sched(SchedHandle { sched_id: ref id, ..}))) => {
-                    rtdebug!("homed task in sched check ****");
-                    *id == sched_id
-                }
-                GreenTask(None) => {
-                    rtabort!("task without home");
-                }
-                SchedTask => {
-                    rtabort!("type error: expected: GreenTask, found: SchedTask");
-                }
+        let mut task = Local::borrow(None::<Task>);
+        let sched_id = task.get().sched.get_ref().sched_id();
+        let sched_run_anything = task.get().sched.get_ref().run_anything;
+        match task.get().task_type {
+            GreenTask(Some(AnySched)) => {
+                rtdebug!("anysched task in sched check ****");
+                sched_run_anything
+            }
+            GreenTask(Some(Sched(SchedHandle { sched_id: ref id, ..}))) => {
+                rtdebug!("homed task in sched check ****");
+                *id == sched_id
+            }
+            GreenTask(None) => {
+                rtabort!("task without home");
             }
-        })
+            SchedTask => {
+                rtabort!("type error: expected: GreenTask, found: SchedTask");
+            }
+        }
     }
 }
 
@@ -433,16 +426,16 @@ impl Coroutine {
     }
 
     fn build_start_wrapper(start: proc()) -> proc() {
-        let start_cell = Cell::new(start);
         let wrapper: proc() = proc() {
             // First code after swap to this new context. Run our
             // cleanup job.
             unsafe {
 
                 // Again - might work while safe, or it might not.
-                Local::borrow(|sched: &mut Scheduler| {
-                    sched.run_cleanup_job();
-                });
+                {
+                    let mut sched = Local::borrow(None::<Scheduler>);
+                    sched.get().run_cleanup_job();
+                }
 
                 // To call the run method on a task we need a direct
                 // reference to it. The task is in TLS, so we can
@@ -451,6 +444,7 @@ impl Coroutine {
                 // need to unsafe_borrow.
                 let task: *mut Task = Local::unsafe_borrow();
 
+                let mut start_cell = Some(start);
                 (*task).run(|| {
                     // N.B. Removing `start` from the start wrapper
                     // closure by emptying a cell is critical for
@@ -462,7 +456,7 @@ impl Coroutine {
                     // be in task context. By moving `start` out of
                     // the closure, all the user code goes our of
                     // scope while the task is still running.
-                    let start = start_cell.take();
+                    let start = start_cell.take_unwrap();
                     start();
                 });
             }
@@ -594,16 +588,19 @@ pub extern "C" fn rust_stack_exhausted() {
         //  #2361 - possible implementation of not using landing pads
 
         if in_green_task_context() {
-            Local::borrow(|task: &mut Task| {
-                let n = task.name.as_ref().map(|n| n.as_slice()).unwrap_or("<unnamed>");
-
-                // See the message below for why this is not emitted to the
-                // task's logger. This has the additional conundrum of the
-                // logger may not be initialized just yet, meaning that an FFI
-                // call would happen to initialized it (calling out to libuv),
-                // and the FFI call needs 2MB of stack when we just ran out.
-                rterrln!("task '{}' has overflowed its stack", n);
-            })
+            let mut task = Local::borrow(None::<Task>);
+            let n = task.get()
+                        .name
+                        .as_ref()
+                        .map(|n| n.as_slice())
+                        .unwrap_or("<unnamed>");
+
+            // See the message below for why this is not emitted to the
+            // task's logger. This has the additional conundrum of the
+            // logger may not be initialized just yet, meaning that an FFI
+            // call would happen to initialized it (calling out to libuv),
+            // and the FFI call needs 2MB of stack when we just ran out.
+            rterrln!("task '{}' has overflowed its stack", n);
         } else {
             rterrln!("stack overflow in non-task context");
         }