sync: fix CancellationToken failing to cancel the ready futures (#7462)

This patch fixes an issue where the `CancellationToken::run_until_cancelled` never cancels the `Future` that returns `Ready` at the first `poll`.

---------

Co-authored-by: Luca BRUNO <[email protected]>
This commit is contained in:
Stepan Tubanov
2025-07-20 10:03:29 +08:00
committed by GitHub
co-authored by Luca BRUNO
parent 0a3fe46086
commit 6d868d96ce
2 changed files with 35 additions and 4 deletions
+20 -4
View File
@@ -268,6 +268,12 @@ impl CancellationToken {
/// unless the [`CancellationToken`] is cancelled. In that case the function returns
/// `None` and the future gets dropped.
///
/// # Fairness
///
/// Calling this on an already-cancelled token directly returns `None`.
/// For all subsequent polls, in case of concurrent completion and
/// cancellation, this is biased towards the future completion.
///
/// # Cancellation safety
///
/// This method is only cancel safe if `fut` is cancel safe.
@@ -303,11 +309,15 @@ impl CancellationToken {
}
}
RunUntilCancelledFuture {
cancellation: self.cancelled(),
future: fut,
if self.is_cancelled() {
None
} else {
RunUntilCancelledFuture {
cancellation: self.cancelled(),
future: fut,
}
.await
}
.await
}
/// Runs a future to completion and returns its result wrapped inside of an `Option`
@@ -316,6 +326,12 @@ impl CancellationToken {
///
/// The function takes self by value and returns a future that owns the token.
///
/// # Fairness
///
/// Calling this on an already-cancelled token directly returns `None`.
/// For all subsequent polls, in case of concurrent completion and
/// cancellation, this is biased towards the future completion.
///
/// # Cancellation safety
///
/// This method is only cancel safe if `fut` is cancel safe.