about summary refs log tree commit diff
path: root/src/librustrt/task.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustrt/task.rs')
-rw-r--r--src/librustrt/task.rs25
1 files changed, 16 insertions, 9 deletions
diff --git a/src/librustrt/task.rs b/src/librustrt/task.rs
index 7e657d3aef3..37632f509c1 100644
--- a/src/librustrt/task.rs
+++ b/src/librustrt/task.rs
@@ -21,6 +21,7 @@ use core::any::Any;
 use core::atomic::{AtomicUint, SeqCst};
 use core::iter::{IteratorExt, Take};
 use core::kinds::marker;
+use core::ops::FnOnce;
 use core::mem;
 use core::ops::FnMut;
 use core::prelude::{Clone, Drop, Err, Iterator, None, Ok, Option, Send, Some};
@@ -34,6 +35,7 @@ use stack;
 use unwind;
 use unwind::Unwinder;
 use collections::str::SendStr;
+use thunk::Thunk;
 
 /// State associated with Rust tasks.
 ///
@@ -67,7 +69,7 @@ enum TaskState {
 
 pub struct TaskOpts {
     /// Invoke this procedure with the result of the task when it finishes.
-    pub on_exit: Option<proc(Result): Send>,
+    pub on_exit: Option<Thunk<Result>>,
     /// A name for the task-to-be, for identification in panic messages
     pub name: Option<SendStr>,
     /// The size of the stack for the spawned task
@@ -92,7 +94,7 @@ pub enum BlockedTask {
 
 /// Per-task state related to task death, killing, panic, etc.
 pub struct Death {
-    pub on_exit: Option<proc(Result):Send>,
+    pub on_exit: Option<Thunk<Result>>,
     marker: marker::NoCopy,
 }
 
@@ -116,7 +118,13 @@ impl Task {
         }
     }
 
-    pub fn spawn(opts: TaskOpts, f: proc():Send) {
+    pub fn spawn<F>(opts: TaskOpts, f: F)
+        where F : FnOnce(), F : Send
+    {
+        Task::spawn_thunk(opts, Thunk::new(f))
+    }
+
+    fn spawn_thunk(opts: TaskOpts, f: Thunk) {
         let TaskOpts { name, stack_size, on_exit } = opts;
 
         let mut task = box Task::new(None, None);
@@ -138,7 +146,7 @@ impl Task {
         // because by the time that this function is executing we've already
         // consumed at least a little bit of stack (we don't know the exact byte
         // address at which our stack started).
-        Thread::spawn_stack(stack, proc() {
+        Thread::spawn_stack(stack, move|| {
             let something_around_the_top_of_the_stack = 1;
             let addr = &something_around_the_top_of_the_stack as *const int;
             let my_stack = addr as uint;
@@ -150,7 +158,7 @@ impl Task {
             task.stack_bounds = (my_stack - stack + 1024, my_stack);
 
             let mut f = Some(f);
-            drop(task.run(|| { f.take().unwrap()() }).destroy());
+            drop(task.run(|| { f.take().unwrap().invoke(()) }).destroy());
             drop(token);
         })
     }
@@ -241,7 +249,7 @@ impl Task {
         //        reconsideration to whether it's a reasonable thing to let a
         //        task to do or not.
         match what_to_do {
-            Some(f) => { f(result) }
+            Some(f) => { f.invoke(result) }
             None => { drop(result) }
         }
 
@@ -500,14 +508,13 @@ mod test {
     use super::*;
     use std::prelude::*;
     use std::task;
-    use unwind;
 
     #[test]
     fn unwind() {
-        let result = task::try(proc()());
+        let result = task::try(move|| ());
         rtdebug!("trying first assert");
         assert!(result.is_ok());
-        let result = task::try::<()>(proc() panic!());
+        let result = task::try(move|| -> () panic!());
         rtdebug!("trying second assert");
         assert!(result.is_err());
     }