Skip to content

Commit

Permalink
Made std::task::TaskBuilder::future_result() easier to use
Browse files Browse the repository at this point in the history
  • Loading branch information
Kimundi committed Oct 18, 2013
1 parent d4a3238 commit 3011801
Show file tree
Hide file tree
Showing 15 changed files with 47 additions and 88 deletions.
2 changes: 1 addition & 1 deletion src/libextra/arc.rs
Expand Up @@ -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);
Expand Down
6 changes: 2 additions & 4 deletions src/libextra/test.rs
Expand Up @@ -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));
Expand Down
1 change: 0 additions & 1 deletion src/libstd/result.rs
Expand Up @@ -463,7 +463,6 @@ mod tests {
use str::OwnedStr;
use vec::ImmutableVector;
use to_str::ToStr;
use fmt::Default;

pub fn op1() -> Result<int, ~str> { Ok(666) }
pub fn op2() -> Result<int, ~str> { Err(~"sadface") }
Expand Down
25 changes: 0 additions & 25 deletions src/libstd/rt/task.rs
Expand Up @@ -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);
}
}
}
57 changes: 26 additions & 31 deletions src/libstd/task/mod.rs
Expand Up @@ -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<TaskResult>)) {
/// 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<TaskResult> {
// 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
Expand All @@ -288,10 +286,10 @@ impl TaskBuilder {
// Construct the future and give it to the caller.
let (notify_pipe_po, notify_pipe_ch) = stream::<TaskResult>();

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
Expand Down Expand Up @@ -398,15 +396,14 @@ impl TaskBuilder {
*/
pub fn try<T:Send>(&mut self, f: ~fn() -> T) -> Result<T,()> {
let (po, ch) = stream::<T>();
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(())
}
Expand Down Expand Up @@ -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]
Expand Down
11 changes: 4 additions & 7 deletions src/libstd/unstable/sync.rs
Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion src/test/bench/msgsend-pipes-shared.rs
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/test/bench/msgsend-pipes.rs
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/test/bench/shootout-pfib.rs
Expand Up @@ -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);
}
Expand Down
5 changes: 2 additions & 3 deletions src/test/bench/task-perf-linked-failure.rs
Expand Up @@ -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);
}

Expand Down
5 changes: 2 additions & 3 deletions src/test/run-pass/task-comm-12.rs
Expand Up @@ -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)
}
Expand All @@ -33,7 +32,7 @@ fn test00() {
}

// Try joining tasks that have already finished.
result.unwrap().recv();
result.recv();

info2!("Joined task.");
}
2 changes: 1 addition & 1 deletion src/test/run-pass/task-comm-3.rs
Expand Up @@ -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)
Expand Down
5 changes: 2 additions & 3 deletions src/test/run-pass/task-comm-9.rs
Expand Up @@ -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);
}
Expand All @@ -42,7 +41,7 @@ fn test00() {
i += 1;
}

result.unwrap().recv();
result.recv();

assert_eq!(sum, number_of_messages * (number_of_messages - 1) / 2);
}
5 changes: 2 additions & 3 deletions src/test/run-pass/yield.rs
Expand Up @@ -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() {
Expand Down
5 changes: 2 additions & 3 deletions src/test/run-pass/yield1.rs
Expand Up @@ -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"); }

5 comments on commit 3011801

@bors
Copy link
Contributor

@bors bors commented on 3011801 Oct 18, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from huonw
at Kimundi@3011801

@bors
Copy link
Contributor

@bors bors commented on 3011801 Oct 18, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging Kimundi/rust/future_result_bad_sig = 3011801 into auto

@bors
Copy link
Contributor

@bors bors commented on 3011801 Oct 18, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kimundi/rust/future_result_bad_sig = 3011801 merged ok, testing candidate = 3f240fe

@bors
Copy link
Contributor

@bors bors commented on 3011801 Oct 18, 2013

@bors
Copy link
Contributor

@bors bors commented on 3011801 Oct 18, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 3f240fe

Please sign in to comment.