Commit e4a39d2 1 parent afd3678 commit e4a39d2 Copy full SHA for e4a39d2
File tree 2 files changed +71
-0
lines changed
2 files changed +71
-0
lines changed Original file line number Diff line number Diff line change @@ -287,6 +287,22 @@ impl CancellationToken {
287
287
}
288
288
. await
289
289
}
290
+
291
+ /// Runs a future to completion and returns its result wrapped inside of an `Option`
292
+ /// unless the `CancellationToken` is cancelled. In that case the function returns
293
+ /// `None` and the future gets dropped.
294
+ ///
295
+ /// The function takes self by value and returns a future that owns the token.
296
+ ///
297
+ /// # Cancel safety
298
+ ///
299
+ /// This method is only cancel safe if `fut` is cancel safe.
300
+ pub async fn run_until_cancelled_owned < F > ( self , fut : F ) -> Option < F :: Output >
301
+ where
302
+ F : Future ,
303
+ {
304
+ self . run_until_cancelled ( fut) . await
305
+ }
290
306
}
291
307
292
308
// ===== impl WaitForCancellationFuture =====
Original file line number Diff line number Diff line change @@ -493,3 +493,58 @@ fn run_until_cancelled_test() {
493
493
) ;
494
494
}
495
495
}
496
+
497
+ #[ test]
498
+ fn run_until_cancelled_owned_test ( ) {
499
+ let ( waker, _) = new_count_waker ( ) ;
500
+
501
+ {
502
+ let token = CancellationToken :: new ( ) ;
503
+ let to_cancel = token. clone ( ) ;
504
+
505
+ let takes_ownership = move |token : CancellationToken | {
506
+ token. run_until_cancelled_owned ( std:: future:: pending :: < ( ) > ( ) )
507
+ } ;
508
+
509
+ let fut = takes_ownership ( token) ;
510
+ pin ! ( fut) ;
511
+
512
+ assert_eq ! (
513
+ Poll :: Pending ,
514
+ fut. as_mut( ) . poll( & mut Context :: from_waker( & waker) )
515
+ ) ;
516
+
517
+ to_cancel. cancel ( ) ;
518
+
519
+ assert_eq ! (
520
+ Poll :: Ready ( None ) ,
521
+ fut. as_mut( ) . poll( & mut Context :: from_waker( & waker) )
522
+ ) ;
523
+ }
524
+
525
+ {
526
+ let ( tx, rx) = oneshot:: channel :: < ( ) > ( ) ;
527
+
528
+ let token = CancellationToken :: new ( ) ;
529
+ let takes_ownership = move |token : CancellationToken , rx : oneshot:: Receiver < ( ) > | {
530
+ token. run_until_cancelled_owned ( async move {
531
+ rx. await . unwrap ( ) ;
532
+ 42
533
+ } )
534
+ } ;
535
+ let fut = takes_ownership ( token, rx) ;
536
+ pin ! ( fut) ;
537
+
538
+ assert_eq ! (
539
+ Poll :: Pending ,
540
+ fut. as_mut( ) . poll( & mut Context :: from_waker( & waker) )
541
+ ) ;
542
+
543
+ tx. send ( ( ) ) . unwrap ( ) ;
544
+
545
+ assert_eq ! (
546
+ Poll :: Ready ( Some ( 42 ) ) ,
547
+ fut. as_mut( ) . poll( & mut Context :: from_waker( & waker) )
548
+ ) ;
549
+ }
550
+ }
You can’t perform that action at this time.
0 commit comments