summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorBen Blum <bblum@andrew.cmu.edu>2012-08-07 14:17:24 -0400
committerBen Blum <bblum@andrew.cmu.edu>2012-08-07 14:26:41 -0400
commitae6d84f573a802ff3606d59a52155380220b3c87 (patch)
tree95e7775b5f85b1035a43abb2ea366753cb576aa0 /src/libcore
parent0cc6cefaec4cedfc91ec7de447e116e6eba82915 (diff)
downloadrust-ae6d84f573a802ff3606d59a52155380220b3c87.tar.gz
rust-ae6d84f573a802ff3606d59a52155380220b3c87.zip
Rework task::try for new task_builder interface (close #3103)
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/task.rs58
1 files changed, 41 insertions, 17 deletions
diff --git a/src/libcore/task.rs b/src/libcore/task.rs
index 61350c1739d..06f3c0b2f50 100644
--- a/src/libcore/task.rs
+++ b/src/libcore/task.rs
@@ -267,6 +267,9 @@ impl task_builder for task_builder {
      * builder. If additional tasks are spawned with the same builder
      * then a new result future must be obtained prior to spawning each
      * task.
+     *
+     * # Failure
+     * Fails if a future_result was already set for this task.
      */
     fn future_result(blk: fn(-future::future<task_result>)) -> task_builder {
         // FIXME (#1087, #1857): Once linked failure and notification are
@@ -274,6 +277,10 @@ impl task_builder for task_builder {
         // registering an arbitrary number of task::on_exit handlers and
         // sending out messages.
 
+        if self.opts.notify_chan.is_some() {
+            fail ~"Can't set multiple future_results for one task!";
+        }
+
         // Construct the future and give it to the caller.
         let po = comm::port::<notification>();
         let ch = comm::chan(po);
@@ -368,6 +375,33 @@ impl task_builder for task_builder {
         }
         comm::recv(setup_po)
     }
+
+    /**
+     * Execute a function in another task and return either the return value
+     * of the function or result::err.
+     *
+     * # Return value
+     *
+     * If the function executed successfully then try returns result::ok
+     * containing the value returned by the function. If the function fails
+     * then try returns result::err containing nil.
+     *
+     * # Failure
+     * Fails if a future_result was already set for this task.
+     */
+    fn try<T: send>(+f: fn~() -> T) -> result<T,()> {
+        let po = comm::port();
+        let ch = comm::chan(po);
+        let mut result = none;
+
+        do self.future_result(|-r| { result = some(r); }).spawn {
+            comm::send(ch, f());
+        }
+        match future::get(option::unwrap(result)) {
+            success => result::ok(comm::recv(po)),
+            failure => result::err(())
+        }
+    }
 }
 
 
@@ -487,25 +521,10 @@ fn try<T:send>(+f: fn~() -> T) -> result<T,()> {
      * Execute a function in another task and return either the return value
      * of the function or result::err.
      *
-     * # Return value
-     *
-     * If the function executed successfully then try returns result::ok
-     * containing the value returned by the function. If the function fails
-     * then try returns result::err containing nil.
+     * This is equivalent to task().supervised().try.
      */
 
-    let po = comm::port();
-    let ch = comm::chan(po);
-
-    let mut result = none;
-
-    do task().unlinked().future_result(|-r| { result = some(r); }).spawn {
-        comm::send(ch, f());
-    }
-    match future::get(option::unwrap(result)) {
-      success => result::ok(comm::recv(po)),
-      failure => result::err(())
-    }
+    task().supervised().try(f)
 }
 
 
@@ -1675,6 +1694,11 @@ fn test_future_result() {
     assert future::get(option::unwrap(result)) == failure;
 }
 
+#[test] #[should_fail] #[ignore(cfg(windows))]
+fn test_back_to_the_future_result() {
+    let _ = task().future_result(|-r| ()).future_result(|-r| ());
+}
+
 #[test]
 fn test_spawn_listiner_bidi() {
     let po = comm::port();