Made std::task::TaskBuilder::future_result()
easier to use
This commit is contained in:
parent
d4a32386f3
commit
3011801256
15 changed files with 47 additions and 88 deletions
|
@ -823,7 +823,7 @@ mod tests {
|
||||||
do 5.times {
|
do 5.times {
|
||||||
let arc3 = arc.clone();
|
let arc3 = arc.clone();
|
||||||
let mut builder = task::task();
|
let mut builder = task::task();
|
||||||
builder.future_result(|r| children.push(r));
|
children.push(builder.future_result());
|
||||||
do builder.spawn {
|
do builder.spawn {
|
||||||
do arc3.read |num| {
|
do arc3.read |num| {
|
||||||
assert!(*num >= 0);
|
assert!(*num >= 0);
|
||||||
|
|
|
@ -870,14 +870,12 @@ pub fn run_test(force_ignore: bool,
|
||||||
testfn: ~fn()) {
|
testfn: ~fn()) {
|
||||||
let testfn_cell = ::std::cell::Cell::new(testfn);
|
let testfn_cell = ::std::cell::Cell::new(testfn);
|
||||||
do task::spawn {
|
do task::spawn {
|
||||||
let mut result_future = None; // task::future_result(builder);
|
|
||||||
|
|
||||||
let mut task = task::task();
|
let mut task = task::task();
|
||||||
task.unlinked();
|
task.unlinked();
|
||||||
task.future_result(|r| { result_future = Some(r) });
|
let result_future = task.future_result();
|
||||||
task.spawn(testfn_cell.take());
|
task.spawn(testfn_cell.take());
|
||||||
|
|
||||||
let task_result = result_future.unwrap().recv();
|
let task_result = result_future.recv();
|
||||||
let test_result = calc_result(&desc,
|
let test_result = calc_result(&desc,
|
||||||
task_result == task::Success);
|
task_result == task::Success);
|
||||||
monitor_ch.send((desc.clone(), test_result));
|
monitor_ch.send((desc.clone(), test_result));
|
||||||
|
|
|
@ -463,7 +463,6 @@ mod tests {
|
||||||
use str::OwnedStr;
|
use str::OwnedStr;
|
||||||
use vec::ImmutableVector;
|
use vec::ImmutableVector;
|
||||||
use to_str::ToStr;
|
use to_str::ToStr;
|
||||||
use fmt::Default;
|
|
||||||
|
|
||||||
pub fn op1() -> Result<int, ~str> { Ok(666) }
|
pub fn op1() -> Result<int, ~str> { Ok(666) }
|
||||||
pub fn op2() -> Result<int, ~str> { Err(~"sadface") }
|
pub fn op2() -> Result<int, ~str> { Err(~"sadface") }
|
||||||
|
|
|
@ -621,29 +621,4 @@ mod test {
|
||||||
a.next = Some(b);
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,24 +258,22 @@ impl TaskBuilder {
|
||||||
self.opts.indestructible = true;
|
self.opts.indestructible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Get a future representing the exit status of the task.
|
||||||
* Get a future representing the exit status of the task.
|
///
|
||||||
*
|
/// Taking the value of the future will block until the child 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
|
||||||
* terminates. The future-receiving callback specified will be called
|
/// spawned; as such, do not invoke .get() on it directly;
|
||||||
* *before* the task is spawned; as such, do not invoke .get() within the
|
/// rather, store it in an outer variable/list for later use.
|
||||||
* closure; rather, store it in an outer variable/list for later use.
|
///
|
||||||
*
|
/// Note that the future returned by this function is only useful for
|
||||||
* Note that the future returning by this function is only useful for
|
/// obtaining the value of the next task to be spawning with the
|
||||||
* obtaining the value of the next task to be spawning with the
|
/// builder. If additional tasks are spawned with the same builder
|
||||||
* builder. If additional tasks are spawned with the same builder
|
/// then a new result future must be obtained prior to spawning each
|
||||||
* then a new result future must be obtained prior to spawning each
|
/// task.
|
||||||
* task.
|
///
|
||||||
*
|
/// # Failure
|
||||||
* # Failure
|
/// Fails if a future_result was already set for this task.
|
||||||
* Fails if a future_result was already set for this task.
|
pub fn future_result(&mut self) -> Port<TaskResult> {
|
||||||
*/
|
|
||||||
pub fn future_result(&mut self, blk: &fn(v: Port<TaskResult>)) {
|
|
||||||
// FIXME (#3725): Once linked failure and notification are
|
// FIXME (#3725): Once linked failure and notification are
|
||||||
// handled in the library, I can imagine implementing this by just
|
// handled in the library, I can imagine implementing this by just
|
||||||
// registering an arbitrary number of task::on_exit handlers and
|
// 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.
|
// Construct the future and give it to the caller.
|
||||||
let (notify_pipe_po, notify_pipe_ch) = stream::<TaskResult>();
|
let (notify_pipe_po, notify_pipe_ch) = stream::<TaskResult>();
|
||||||
|
|
||||||
blk(notify_pipe_po);
|
|
||||||
|
|
||||||
// Reconfigure self to use a notify channel.
|
// Reconfigure self to use a notify channel.
|
||||||
self.opts.notify_chan = Some(notify_pipe_ch);
|
self.opts.notify_chan = Some(notify_pipe_ch);
|
||||||
|
|
||||||
|
notify_pipe_po
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Name the task-to-be. Currently the name is used for identification
|
/// Name the task-to-be. Currently the name is used for identification
|
||||||
|
@ -398,15 +396,14 @@ impl TaskBuilder {
|
||||||
*/
|
*/
|
||||||
pub fn try<T:Send>(&mut self, f: ~fn() -> T) -> Result<T,()> {
|
pub fn try<T:Send>(&mut self, f: ~fn() -> T) -> Result<T,()> {
|
||||||
let (po, ch) = stream::<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 {
|
do self.spawn {
|
||||||
ch.send(f());
|
ch.send(f());
|
||||||
}
|
}
|
||||||
|
|
||||||
match result.unwrap().recv() {
|
match result.recv() {
|
||||||
Success => result::Ok(po.recv()),
|
Success => result::Ok(po.recv()),
|
||||||
Failure => result::Err(())
|
Failure => result::Err(())
|
||||||
}
|
}
|
||||||
|
@ -1024,27 +1021,25 @@ fn test_add_wrapper() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_future_result() {
|
fn test_future_result() {
|
||||||
let mut result = None;
|
|
||||||
let mut builder = task();
|
let mut builder = task();
|
||||||
builder.future_result(|r| result = Some(r));
|
let result = builder.future_result();
|
||||||
do builder.spawn {}
|
do builder.spawn {}
|
||||||
assert_eq!(result.unwrap().recv(), Success);
|
assert_eq!(result.recv(), Success);
|
||||||
|
|
||||||
result = None;
|
|
||||||
let mut builder = task();
|
let mut builder = task();
|
||||||
builder.future_result(|r| result = Some(r));
|
let result = builder.future_result();
|
||||||
builder.unlinked();
|
builder.unlinked();
|
||||||
do builder.spawn {
|
do builder.spawn {
|
||||||
fail2!();
|
fail2!();
|
||||||
}
|
}
|
||||||
assert_eq!(result.unwrap().recv(), Failure);
|
assert_eq!(result.recv(), Failure);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] #[should_fail]
|
#[test] #[should_fail]
|
||||||
fn test_back_to_the_future_result() {
|
fn test_back_to_the_future_result() {
|
||||||
let mut builder = task();
|
let mut builder = task();
|
||||||
builder.future_result(util::ignore);
|
builder.future_result();
|
||||||
builder.future_result(util::ignore);
|
builder.future_result();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -580,32 +580,29 @@ mod tests {
|
||||||
// Now try the same thing, but with the child task blocking.
|
// Now try the same thing, but with the child task blocking.
|
||||||
let x = Exclusive::new(~~"hello");
|
let x = Exclusive::new(~~"hello");
|
||||||
let x2 = Cell::new(x.clone());
|
let x2 = Cell::new(x.clone());
|
||||||
let mut res = None;
|
|
||||||
let mut builder = task::task();
|
let mut builder = task::task();
|
||||||
builder.future_result(|r| res = Some(r));
|
let res = builder.future_result();
|
||||||
do builder.spawn {
|
do builder.spawn {
|
||||||
let x2 = x2.take();
|
let x2 = x2.take();
|
||||||
assert!(x2.unwrap() == ~~"hello");
|
assert!(x2.unwrap() == ~~"hello");
|
||||||
}
|
}
|
||||||
// Have to get rid of our reference before blocking.
|
// Have to get rid of our reference before blocking.
|
||||||
util::ignore(x);
|
util::ignore(x);
|
||||||
res.unwrap().recv();
|
res.recv();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] #[should_fail]
|
#[test] #[should_fail]
|
||||||
fn exclusive_new_unwrap_conflict() {
|
fn exclusive_new_unwrap_conflict() {
|
||||||
let x = Exclusive::new(~~"hello");
|
let x = Exclusive::new(~~"hello");
|
||||||
let x2 = Cell::new(x.clone());
|
let x2 = Cell::new(x.clone());
|
||||||
let mut res = None;
|
|
||||||
let mut builder = task::task();
|
let mut builder = task::task();
|
||||||
builder.future_result(|r| res = Some(r));
|
let res = builder.future_result();
|
||||||
do builder.spawn {
|
do builder.spawn {
|
||||||
let x2 = x2.take();
|
let x2 = x2.take();
|
||||||
assert!(x2.unwrap() == ~~"hello");
|
assert!(x2.unwrap() == ~~"hello");
|
||||||
}
|
}
|
||||||
assert!(x.unwrap() == ~~"hello");
|
assert!(x.unwrap() == ~~"hello");
|
||||||
// See #4689 for why this can't be just "res.recv()".
|
assert!(res.recv() == task::Success);
|
||||||
assert!(res.unwrap().recv() == task::Success);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -67,7 +67,7 @@ fn run(args: &[~str]) {
|
||||||
for _ in range(0u, workers) {
|
for _ in range(0u, workers) {
|
||||||
let to_child = to_child.clone();
|
let to_child = to_child.clone();
|
||||||
let mut builder = task::task();
|
let mut builder = task::task();
|
||||||
builder.future_result(|r| worker_results.push(r));
|
worker_results.push(builder.future_result());
|
||||||
do builder.spawn {
|
do builder.spawn {
|
||||||
for _ in range(0u, size / workers) {
|
for _ in range(0u, size / workers) {
|
||||||
//error2!("worker {:?}: sending {:?} bytes", i, num_bytes);
|
//error2!("worker {:?}: sending {:?} bytes", i, num_bytes);
|
||||||
|
|
|
@ -61,7 +61,7 @@ fn run(args: &[~str]) {
|
||||||
for _ in range(0u, workers) {
|
for _ in range(0u, workers) {
|
||||||
let to_child = to_child.clone();
|
let to_child = to_child.clone();
|
||||||
let mut builder = task::task();
|
let mut builder = task::task();
|
||||||
builder.future_result(|r| worker_results.push(r));
|
worker_results.push(builder.future_result());
|
||||||
do builder.spawn {
|
do builder.spawn {
|
||||||
for _ in range(0u, size / workers) {
|
for _ in range(0u, size / workers) {
|
||||||
//error2!("worker {:?}: sending {:?} bytes", i, num_bytes);
|
//error2!("worker {:?}: sending {:?} bytes", i, num_bytes);
|
||||||
|
|
|
@ -84,7 +84,7 @@ fn stress(num_tasks: int) {
|
||||||
let mut results = ~[];
|
let mut results = ~[];
|
||||||
for i in range(0, num_tasks) {
|
for i in range(0, num_tasks) {
|
||||||
let mut builder = task::task();
|
let mut builder = task::task();
|
||||||
builder.future_result(|r| results.push(r));
|
results.push(builder.future_result());
|
||||||
do builder.spawn {
|
do builder.spawn {
|
||||||
stress_task(i);
|
stress_task(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,13 +54,12 @@ fn grandchild_group(num_tasks: uint) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_supervised_blocking(myname: &str, f: ~fn()) {
|
fn spawn_supervised_blocking(myname: &str, f: ~fn()) {
|
||||||
let mut res = None;
|
|
||||||
let mut builder = task::task();
|
let mut builder = task::task();
|
||||||
builder.future_result(|r| res = Some(r));
|
let res = builder.future_result();
|
||||||
builder.supervised();
|
builder.supervised();
|
||||||
builder.spawn(f);
|
builder.spawn(f);
|
||||||
error2!("{} group waiting", myname);
|
error2!("{} group waiting", myname);
|
||||||
let x = res.unwrap().recv();
|
let x = res.recv();
|
||||||
assert_eq!(x, task::Success);
|
assert_eq!(x, task::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,8 @@ fn start(_task_number: int) { info2!("Started / Finished task."); }
|
||||||
|
|
||||||
fn test00() {
|
fn test00() {
|
||||||
let i: int = 0;
|
let i: int = 0;
|
||||||
let mut result = None;
|
|
||||||
let mut builder = task::task();
|
let mut builder = task::task();
|
||||||
builder.future_result(|r| result = Some(r));
|
let result = builder.future_result();
|
||||||
do builder.spawn {
|
do builder.spawn {
|
||||||
start(i)
|
start(i)
|
||||||
}
|
}
|
||||||
|
@ -33,7 +32,7 @@ fn test00() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try joining tasks that have already finished.
|
// Try joining tasks that have already finished.
|
||||||
result.unwrap().recv();
|
result.recv();
|
||||||
|
|
||||||
info2!("Joined task.");
|
info2!("Joined task.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ fn test00() {
|
||||||
while i < number_of_tasks {
|
while i < number_of_tasks {
|
||||||
let ch = ch.clone();
|
let ch = ch.clone();
|
||||||
let mut builder = task::task();
|
let mut builder = task::task();
|
||||||
builder.future_result(|r| results.push(r));
|
results.push(builder.future_result());
|
||||||
builder.spawn({
|
builder.spawn({
|
||||||
let i = i;
|
let i = i;
|
||||||
|| test00_start(&ch, i, number_of_messages)
|
|| test00_start(&ch, i, number_of_messages)
|
||||||
|
|
|
@ -28,9 +28,8 @@ fn test00() {
|
||||||
let (p, ch) = comm::stream();
|
let (p, ch) = comm::stream();
|
||||||
let number_of_messages: int = 10;
|
let number_of_messages: int = 10;
|
||||||
|
|
||||||
let mut result = None;
|
|
||||||
let mut builder = task::task();
|
let mut builder = task::task();
|
||||||
builder.future_result(|r| result = Some(r));
|
let result = builder.future_result();
|
||||||
do builder.spawn {
|
do builder.spawn {
|
||||||
test00_start(&ch, number_of_messages);
|
test00_start(&ch, number_of_messages);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +41,7 @@ fn test00() {
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.unwrap().recv();
|
result.recv();
|
||||||
|
|
||||||
assert_eq!(sum, number_of_messages * (number_of_messages - 1) / 2);
|
assert_eq!(sum, number_of_messages * (number_of_messages - 1) / 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,15 @@
|
||||||
use std::task;
|
use std::task;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let mut result = None;
|
|
||||||
let mut builder = task::task();
|
let mut builder = task::task();
|
||||||
builder.future_result(|r| { result = Some(r); });
|
let result = builder.future_result();
|
||||||
builder.spawn(child);
|
builder.spawn(child);
|
||||||
error2!("1");
|
error2!("1");
|
||||||
task::deschedule();
|
task::deschedule();
|
||||||
error2!("2");
|
error2!("2");
|
||||||
task::deschedule();
|
task::deschedule();
|
||||||
error2!("3");
|
error2!("3");
|
||||||
result.unwrap().recv();
|
result.recv();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn child() {
|
fn child() {
|
||||||
|
|
|
@ -12,13 +12,12 @@
|
||||||
use std::task;
|
use std::task;
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let mut result = None;
|
|
||||||
let mut builder = task::task();
|
let mut builder = task::task();
|
||||||
builder.future_result(|r| { result = Some(r); });
|
let result = builder.future_result();
|
||||||
builder.spawn(child);
|
builder.spawn(child);
|
||||||
error2!("1");
|
error2!("1");
|
||||||
task::deschedule();
|
task::deschedule();
|
||||||
result.unwrap().recv();
|
result.recv();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn child() { error2!("2"); }
|
fn child() { error2!("2"); }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue