@@ -267,13 +267,20 @@ impl task_builder for task_builder {
267
267
* builder. If additional tasks are spawned with the same builder
268
268
* then a new result future must be obtained prior to spawning each
269
269
* task.
270
+ *
271
+ * # Failure
272
+ * Fails if a future_result was already set for this task.
270
273
*/
271
274
fn future_result( blk : fn ( -future:: future < task_result > ) ) -> task_builder {
272
275
// FIXME (#1087, #1857): Once linked failure and notification are
273
276
// handled in the library, I can imagine implementing this by just
274
277
// registering an arbitrary number of task::on_exit handlers and
275
278
// sending out messages.
276
279
280
+ if self . opts . notify_chan . is_some ( ) {
281
+ fail ~"Can ' t set multiple future_results for one task!";
282
+ }
283
+
277
284
// Construct the future and give it to the caller.
278
285
let po = comm::port::<notification>();
279
286
let ch = comm::chan(po);
@@ -368,6 +375,33 @@ impl task_builder for task_builder {
368
375
}
369
376
comm::recv(setup_po)
370
377
}
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
+ }
371
405
}
372
406
373
407
@@ -487,25 +521,10 @@ fn try<T:send>(+f: fn~() -> T) -> result<T,()> {
487
521
* Execute a function in another task and return either the return value
488
522
* of the function or result::err.
489
523
*
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.
495
525
*/
496
526
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)
509
528
}
510
529
511
530
@@ -1675,6 +1694,11 @@ fn test_future_result() {
1675
1694
assert future:: get( option:: unwrap( result) ) == failure;
1676
1695
}
1677
1696
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
+
1678
1702
#[ test]
1679
1703
fn test_spawn_listiner_bidi ( ) {
1680
1704
let po = comm: : port( ) ;
0 commit comments