auto merge of #9926 : Kimundi/rust/future_result_bad_sig, r=huonw
This commit is contained in:
commit
3f240fedec
15 changed files with 47 additions and 88 deletions
|
|
@ -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") }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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(())
|
||||
}
|
||||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue