Skip to content

Commit b926700

Browse files
authored
sync: add DropGuardRef for CancellationToken (#7407)
1 parent 99a03a5 commit b926700

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

tokio-util/src/sync/cancellation_token.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! An asynchronously awaitable `CancellationToken`.
22
//! The token allows to signal a cancellation request to one or more tasks.
33
pub(crate) mod guard;
4+
pub(crate) mod guard_ref;
45
mod tree_node;
56

67
use crate::loom::sync::Arc;
@@ -10,6 +11,7 @@ use core::pin::Pin;
1011
use core::task::{Context, Poll};
1112

1213
use guard::DropGuard;
14+
use guard_ref::DropGuardRef;
1315
use pin_project_lite::pin_project;
1416

1517
/// A token which can be used to signal a cancellation request to one or more
@@ -242,6 +244,14 @@ impl CancellationToken {
242244
DropGuard { inner: Some(self) }
243245
}
244246

247+
/// Creates a `DropGuardRef` for this token.
248+
///
249+
/// Returned guard will cancel this token (and all its children) on drop
250+
/// unless disarmed.
251+
pub fn drop_guard_ref(&self) -> DropGuardRef<'_> {
252+
DropGuardRef { inner: Some(self) }
253+
}
254+
245255
/// Runs a future to completion and returns its result wrapped inside of an `Option`
246256
/// unless the `CancellationToken` is cancelled. In that case the function returns
247257
/// `None` and the future gets dropped.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use crate::sync::CancellationToken;
2+
3+
/// A wrapper for cancellation token which automatically cancels
4+
/// it on drop. It is created using `drop_guard_ref` method on the `CancellationToken`.
5+
///
6+
/// This is a `ref` version of `DropGuard`
7+
#[derive(Debug)]
8+
pub struct DropGuardRef<'a> {
9+
pub(super) inner: Option<&'a CancellationToken>,
10+
}
11+
12+
impl<'a> DropGuardRef<'a> {
13+
/// Returns stored cancellation token and removes this drop guard instance
14+
/// (i.e. it will no longer cancel token). Other guards for this token
15+
/// are not affected.
16+
pub fn disarm(mut self) -> &'a CancellationToken {
17+
self.inner
18+
.take()
19+
.expect("`inner` can be only None in a destructor")
20+
}
21+
}
22+
23+
impl Drop for DropGuardRef<'_> {
24+
fn drop(&mut self) {
25+
if let Some(inner) = self.inner {
26+
inner.cancel();
27+
}
28+
}
29+
}

tokio-util/src/sync/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
33
mod cancellation_token;
44
pub use cancellation_token::{
5-
guard::DropGuard, CancellationToken, WaitForCancellationFuture, WaitForCancellationFutureOwned,
5+
guard::DropGuard, guard_ref::DropGuardRef, CancellationToken, WaitForCancellationFuture,
6+
WaitForCancellationFutureOwned,
67
};
78

89
mod mpsc;

0 commit comments

Comments
 (0)