Skip to content

Commit ae6d84f

Browse files
committed
Rework task::try for new task_builder interface (close #3103)
1 parent 0cc6cef commit ae6d84f

File tree

1 file changed

+41
-17
lines changed

1 file changed

+41
-17
lines changed

src/libcore/task.rs

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -267,13 +267,20 @@ impl task_builder for task_builder {
267267
* builder. If additional tasks are spawned with the same builder
268268
* then a new result future must be obtained prior to spawning each
269269
* task.
270+
*
271+
* # Failure
272+
* Fails if a future_result was already set for this task.
270273
*/
271274
fn future_result(blk: fn(-future::future<task_result>)) -> task_builder {
272275
// FIXME (#1087, #1857): Once linked failure and notification are
273276
// handled in the library, I can imagine implementing this by just
274277
// registering an arbitrary number of task::on_exit handlers and
275278
// sending out messages.
276279

280+
if self.opts.notify_chan.is_some() {
281+
fail ~"Can't set multiple future_results for one task!";
282+
}
283+
277284
// Construct the future and give it to the caller.
278285
let po = comm::port::<notification>();
279286
let ch = comm::chan(po);
@@ -368,6 +375,33 @@ impl task_builder for task_builder {
368375
}
369376
comm::recv(setup_po)
370377
}
378+
379+
/**
380+
* Execute a function in another task and return either the return value
381+
* of the function or result::err.
382+
*
383+
* # Return value
384+
*
385+
* If the function executed successfully then try returns result::ok
386+
* containing the value returned by the function. If the function fails
387+
* then try returns result::err containing nil.
388+
*
389+
* # Failure
390+
* Fails if a future_result was already set for this task.
391+
*/
392+
fn try<T: send>(+f: fn~() -> T) -> result<T,()> {
393+
let po = comm::port();
394+
let ch = comm::chan(po);
395+
let mut result = none;
396+
397+
do self.future_result(|-r| { result = some(r); }).spawn {
398+
comm::send(ch, f());
399+
}
400+
match future::get(option::unwrap(result)) {
401+
success => result::ok(comm::recv(po)),
402+
failure => result::err(())
403+
}
404+
}
371405
}
372406
373407
@@ -487,25 +521,10 @@ fn try<T:send>(+f: fn~() -> T) -> result<T,()> {
487521
* Execute a function in another task and return either the return value
488522
* of the function or result::err.
489523
*
490-
* # Return value
491-
*
492-
* If the function executed successfully then try returns result::ok
493-
* containing the value returned by the function. If the function fails
494-
* then try returns result::err containing nil.
524+
* This is equivalent to task().supervised().try.
495525
*/
496526
497-
let po = comm::port();
498-
let ch = comm::chan(po);
499-
500-
let mut result = none;
501-
502-
do task().unlinked().future_result(|-r| { result = some(r); }).spawn {
503-
comm::send(ch, f());
504-
}
505-
match future::get(option::unwrap(result)) {
506-
success => result::ok(comm::recv(po)),
507-
failure => result::err(())
508-
}
527+
task().supervised().try(f)
509528
}
510529
511530
@@ -1675,6 +1694,11 @@ fn test_future_result() {
16751694
assert future::get(option::unwrap(result)) == failure;
16761695
}
16771696

1697+
#[test] #[should_fail] #[ignore(cfg(windows))]
1698+
fn test_back_to_the_future_result() {
1699+
let _ = task().future_result(|-r| ()).future_result(|-r| ());
1700+
}
1701+
16781702
#[test]
16791703
fn test_spawn_listiner_bidi() {
16801704
let po = comm::port();

0 commit comments

Comments
 (0)