From 3011801256d112e1930726058362b8fd22ea40dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20L=C3=B6bel?= Date: Fri, 18 Oct 2013 10:38:46 +0200 Subject: [PATCH] Made `std::task::TaskBuilder::future_result()` easier to use --- src/libextra/arc.rs | 2 +- src/libextra/test.rs | 6 +-- src/libstd/result.rs | 1 - src/libstd/rt/task.rs | 25 ---------- src/libstd/task/mod.rs | 57 ++++++++++------------ src/libstd/unstable/sync.rs | 11 ++--- src/test/bench/msgsend-pipes-shared.rs | 2 +- src/test/bench/msgsend-pipes.rs | 2 +- src/test/bench/shootout-pfib.rs | 2 +- src/test/bench/task-perf-linked-failure.rs | 5 +- src/test/run-pass/task-comm-12.rs | 5 +- src/test/run-pass/task-comm-3.rs | 2 +- src/test/run-pass/task-comm-9.rs | 5 +- src/test/run-pass/yield.rs | 5 +- src/test/run-pass/yield1.rs | 5 +- 15 files changed, 47 insertions(+), 88 deletions(-) diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 1cb30eaa040..d1e7534795b 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -823,7 +823,7 @@ mod tests { do 5.times { let arc3 = arc.clone(); let mut builder = task::task(); - builder.future_result(|r| children.push(r)); + children.push(builder.future_result()); do builder.spawn { do arc3.read |num| { assert!(*num >= 0); diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 21fa9ed7574..59eea6b4a13 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -870,14 +870,12 @@ pub fn run_test(force_ignore: bool, testfn: ~fn()) { let testfn_cell = ::std::cell::Cell::new(testfn); do task::spawn { - let mut result_future = None; // task::future_result(builder); - let mut task = task::task(); task.unlinked(); - task.future_result(|r| { result_future = Some(r) }); + let result_future = task.future_result(); task.spawn(testfn_cell.take()); - let task_result = result_future.unwrap().recv(); + let task_result = result_future.recv(); let test_result = calc_result(&desc, task_result == task::Success); monitor_ch.send((desc.clone(), test_result)); diff --git a/src/libstd/result.rs b/src/libstd/result.rs index 47e0c099c98..92315b5d47a 100644 --- a/src/libstd/result.rs +++ b/src/libstd/result.rs @@ -463,7 +463,6 @@ mod tests { use str::OwnedStr; use vec::ImmutableVector; use to_str::ToStr; - use fmt::Default; pub fn op1() -> Result { Ok(666) } pub fn op2() -> Result { Err(~"sadface") } diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index d5278975d8d..889d9bb3156 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -621,29 +621,4 @@ mod test { a.next = Some(b); } } - - // XXX: This is a copy of test_future_result in std::task. - // It can be removed once the scheduler is turned on by default. - #[test] - fn future_result() { - do run_in_newsched_task { - use option::{Some, None}; - use task::*; - - let mut result = None; - let mut builder = task(); - builder.future_result(|r| result = Some(r)); - do builder.spawn {} - assert_eq!(result.unwrap().recv(), Success); - - result = None; - let mut builder = task(); - builder.future_result(|r| result = Some(r)); - builder.unlinked(); - do builder.spawn { - fail2!(); - } - assert_eq!(result.unwrap().recv(), Failure); - } - } } diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs index a46e115a503..51b1ab603ed 100644 --- a/src/libstd/task/mod.rs +++ b/src/libstd/task/mod.rs @@ -258,24 +258,22 @@ impl TaskBuilder { self.opts.indestructible = true; } - /** - * Get a future representing the exit status of the task. - * - * Taking the value of the future will block until the child task - * terminates. The future-receiving callback specified will be called - * *before* the task is spawned; as such, do not invoke .get() within the - * closure; rather, store it in an outer variable/list for later use. - * - * Note that the future returning by this function is only useful for - * obtaining the value of the next task to be spawning with the - * 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. - */ - pub fn future_result(&mut self, blk: &fn(v: Port)) { + /// Get a future representing the exit status of the task. + /// + /// Taking the value of the future will block until the child task + /// terminates. The future result return value will be created *before* the task is + /// spawned; as such, do not invoke .get() on it directly; + /// rather, store it in an outer variable/list for later use. + /// + /// Note that the future returned by this function is only useful for + /// obtaining the value of the next task to be spawning with the + /// 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. + pub fn future_result(&mut self) -> Port { // FIXME (#3725): Once linked failure and notification are // handled in the library, I can imagine implementing this by just // registering an arbitrary number of task::on_exit handlers and @@ -288,10 +286,10 @@ impl TaskBuilder { // Construct the future and give it to the caller. let (notify_pipe_po, notify_pipe_ch) = stream::(); - blk(notify_pipe_po); - // Reconfigure self to use a notify channel. self.opts.notify_chan = Some(notify_pipe_ch); + + notify_pipe_po } /// Name the task-to-be. Currently the name is used for identification @@ -398,15 +396,14 @@ impl TaskBuilder { */ pub fn try(&mut self, f: ~fn() -> T) -> Result { let (po, ch) = stream::(); - let mut result = None; - self.future_result(|r| { result = Some(r); }); + let result = self.future_result(); do self.spawn { ch.send(f()); } - match result.unwrap().recv() { + match result.recv() { Success => result::Ok(po.recv()), Failure => result::Err(()) } @@ -1024,27 +1021,25 @@ fn test_add_wrapper() { #[test] fn test_future_result() { - let mut result = None; let mut builder = task(); - builder.future_result(|r| result = Some(r)); + let result = builder.future_result(); do builder.spawn {} - assert_eq!(result.unwrap().recv(), Success); + assert_eq!(result.recv(), Success); - result = None; let mut builder = task(); - builder.future_result(|r| result = Some(r)); + let result = builder.future_result(); builder.unlinked(); do builder.spawn { fail2!(); } - assert_eq!(result.unwrap().recv(), Failure); + assert_eq!(result.recv(), Failure); } #[test] #[should_fail] fn test_back_to_the_future_result() { let mut builder = task(); - builder.future_result(util::ignore); - builder.future_result(util::ignore); + builder.future_result(); + builder.future_result(); } #[test] diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs index f3945d8f3c9..459df572b78 100644 --- a/src/libstd/unstable/sync.rs +++ b/src/libstd/unstable/sync.rs @@ -580,32 +580,29 @@ mod tests { // Now try the same thing, but with the child task blocking. let x = Exclusive::new(~~"hello"); let x2 = Cell::new(x.clone()); - let mut res = None; let mut builder = task::task(); - builder.future_result(|r| res = Some(r)); + let res = builder.future_result(); do builder.spawn { let x2 = x2.take(); assert!(x2.unwrap() == ~~"hello"); } // Have to get rid of our reference before blocking. util::ignore(x); - res.unwrap().recv(); + res.recv(); } #[test] #[should_fail] fn exclusive_new_unwrap_conflict() { let x = Exclusive::new(~~"hello"); let x2 = Cell::new(x.clone()); - let mut res = None; let mut builder = task::task(); - builder.future_result(|r| res = Some(r)); + let res = builder.future_result(); do builder.spawn { let x2 = x2.take(); assert!(x2.unwrap() == ~~"hello"); } assert!(x.unwrap() == ~~"hello"); - // See #4689 for why this can't be just "res.recv()". - assert!(res.unwrap().recv() == task::Success); + assert!(res.recv() == task::Success); } #[test] diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs index 83bb6a37e92..ff2eb575ec5 100644 --- a/src/test/bench/msgsend-pipes-shared.rs +++ b/src/test/bench/msgsend-pipes-shared.rs @@ -67,7 +67,7 @@ fn run(args: &[~str]) { for _ in range(0u, workers) { let to_child = to_child.clone(); let mut builder = task::task(); - builder.future_result(|r| worker_results.push(r)); + worker_results.push(builder.future_result()); do builder.spawn { for _ in range(0u, size / workers) { //error2!("worker {:?}: sending {:?} bytes", i, num_bytes); diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs index ad727318753..4ce9fb493eb 100644 --- a/src/test/bench/msgsend-pipes.rs +++ b/src/test/bench/msgsend-pipes.rs @@ -61,7 +61,7 @@ fn run(args: &[~str]) { for _ in range(0u, workers) { let to_child = to_child.clone(); let mut builder = task::task(); - builder.future_result(|r| worker_results.push(r)); + worker_results.push(builder.future_result()); do builder.spawn { for _ in range(0u, size / workers) { //error2!("worker {:?}: sending {:?} bytes", i, num_bytes); diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index 0f0651f4a4d..b4f6e7e4b71 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -84,7 +84,7 @@ fn stress(num_tasks: int) { let mut results = ~[]; for i in range(0, num_tasks) { let mut builder = task::task(); - builder.future_result(|r| results.push(r)); + results.push(builder.future_result()); do builder.spawn { stress_task(i); } diff --git a/src/test/bench/task-perf-linked-failure.rs b/src/test/bench/task-perf-linked-failure.rs index 03f778ca1d1..3b64cb38c7e 100644 --- a/src/test/bench/task-perf-linked-failure.rs +++ b/src/test/bench/task-perf-linked-failure.rs @@ -54,13 +54,12 @@ fn grandchild_group(num_tasks: uint) { } fn spawn_supervised_blocking(myname: &str, f: ~fn()) { - let mut res = None; let mut builder = task::task(); - builder.future_result(|r| res = Some(r)); + let res = builder.future_result(); builder.supervised(); builder.spawn(f); error2!("{} group waiting", myname); - let x = res.unwrap().recv(); + let x = res.recv(); assert_eq!(x, task::Success); } diff --git a/src/test/run-pass/task-comm-12.rs b/src/test/run-pass/task-comm-12.rs index c640bd32bad..9d5f8937590 100644 --- a/src/test/run-pass/task-comm-12.rs +++ b/src/test/run-pass/task-comm-12.rs @@ -18,9 +18,8 @@ fn start(_task_number: int) { info2!("Started / Finished task."); } fn test00() { let i: int = 0; - let mut result = None; let mut builder = task::task(); - builder.future_result(|r| result = Some(r)); + let result = builder.future_result(); do builder.spawn { start(i) } @@ -33,7 +32,7 @@ fn test00() { } // Try joining tasks that have already finished. - result.unwrap().recv(); + result.recv(); info2!("Joined task."); } diff --git a/src/test/run-pass/task-comm-3.rs b/src/test/run-pass/task-comm-3.rs index 53c3b7f17ea..b4a1a38faa2 100644 --- a/src/test/run-pass/task-comm-3.rs +++ b/src/test/run-pass/task-comm-3.rs @@ -45,7 +45,7 @@ fn test00() { while i < number_of_tasks { let ch = ch.clone(); let mut builder = task::task(); - builder.future_result(|r| results.push(r)); + results.push(builder.future_result()); builder.spawn({ let i = i; || test00_start(&ch, i, number_of_messages) diff --git a/src/test/run-pass/task-comm-9.rs b/src/test/run-pass/task-comm-9.rs index 789425361f8..20d22204bed 100644 --- a/src/test/run-pass/task-comm-9.rs +++ b/src/test/run-pass/task-comm-9.rs @@ -28,9 +28,8 @@ fn test00() { let (p, ch) = comm::stream(); let number_of_messages: int = 10; - let mut result = None; let mut builder = task::task(); - builder.future_result(|r| result = Some(r)); + let result = builder.future_result(); do builder.spawn { test00_start(&ch, number_of_messages); } @@ -42,7 +41,7 @@ fn test00() { i += 1; } - result.unwrap().recv(); + result.recv(); assert_eq!(sum, number_of_messages * (number_of_messages - 1) / 2); } diff --git a/src/test/run-pass/yield.rs b/src/test/run-pass/yield.rs index 48079843dfe..6f6f59d80a5 100644 --- a/src/test/run-pass/yield.rs +++ b/src/test/run-pass/yield.rs @@ -12,16 +12,15 @@ use std::task; pub fn main() { - let mut result = None; let mut builder = task::task(); - builder.future_result(|r| { result = Some(r); }); + let result = builder.future_result(); builder.spawn(child); error2!("1"); task::deschedule(); error2!("2"); task::deschedule(); error2!("3"); - result.unwrap().recv(); + result.recv(); } fn child() { diff --git a/src/test/run-pass/yield1.rs b/src/test/run-pass/yield1.rs index 4cfa3a95236..6b189e515ff 100644 --- a/src/test/run-pass/yield1.rs +++ b/src/test/run-pass/yield1.rs @@ -12,13 +12,12 @@ use std::task; pub fn main() { - let mut result = None; let mut builder = task::task(); - builder.future_result(|r| { result = Some(r); }); + let result = builder.future_result(); builder.spawn(child); error2!("1"); task::deschedule(); - result.unwrap().recv(); + result.recv(); } fn child() { error2!("2"); }