mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-09-28 12:10:37 +00:00

Co-authored-by: Mikail Bagishov <bagishov.mikail@yandex.ru> Co-authored-by: Eliza Weisman <eliza@buoyant.io>
221 lines
5.6 KiB
Rust
221 lines
5.6 KiB
Rust
#![warn(rust_2018_idioms)]
|
|
|
|
use tokio::pin;
|
|
use tokio_util::sync::CancellationToken;
|
|
|
|
use core::future::Future;
|
|
use core::task::{Context, Poll};
|
|
use futures_test::task::new_count_waker;
|
|
|
|
#[test]
|
|
fn cancel_token() {
|
|
let (waker, wake_counter) = new_count_waker();
|
|
let token = CancellationToken::new();
|
|
assert_eq!(false, token.is_cancelled());
|
|
|
|
let wait_fut = token.cancelled();
|
|
pin!(wait_fut);
|
|
|
|
assert_eq!(
|
|
Poll::Pending,
|
|
wait_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
assert_eq!(wake_counter, 0);
|
|
|
|
let wait_fut_2 = token.cancelled();
|
|
pin!(wait_fut_2);
|
|
|
|
token.cancel();
|
|
assert_eq!(wake_counter, 1);
|
|
assert_eq!(true, token.is_cancelled());
|
|
|
|
assert_eq!(
|
|
Poll::Ready(()),
|
|
wait_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
assert_eq!(
|
|
Poll::Ready(()),
|
|
wait_fut_2.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn cancel_child_token_through_parent() {
|
|
let (waker, wake_counter) = new_count_waker();
|
|
let token = CancellationToken::new();
|
|
|
|
let child_token = token.child_token();
|
|
assert!(!child_token.is_cancelled());
|
|
|
|
let child_fut = child_token.cancelled();
|
|
pin!(child_fut);
|
|
let parent_fut = token.cancelled();
|
|
pin!(parent_fut);
|
|
|
|
assert_eq!(
|
|
Poll::Pending,
|
|
child_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
assert_eq!(
|
|
Poll::Pending,
|
|
parent_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
assert_eq!(wake_counter, 0);
|
|
|
|
token.cancel();
|
|
assert_eq!(wake_counter, 2);
|
|
assert_eq!(true, token.is_cancelled());
|
|
assert_eq!(true, child_token.is_cancelled());
|
|
|
|
assert_eq!(
|
|
Poll::Ready(()),
|
|
child_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
assert_eq!(
|
|
Poll::Ready(()),
|
|
parent_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn cancel_child_token_without_parent() {
|
|
let (waker, wake_counter) = new_count_waker();
|
|
let token = CancellationToken::new();
|
|
|
|
let child_token_1 = token.child_token();
|
|
|
|
let child_fut = child_token_1.cancelled();
|
|
pin!(child_fut);
|
|
let parent_fut = token.cancelled();
|
|
pin!(parent_fut);
|
|
|
|
assert_eq!(
|
|
Poll::Pending,
|
|
child_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
assert_eq!(
|
|
Poll::Pending,
|
|
parent_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
assert_eq!(wake_counter, 0);
|
|
|
|
child_token_1.cancel();
|
|
assert_eq!(wake_counter, 1);
|
|
assert_eq!(false, token.is_cancelled());
|
|
assert_eq!(true, child_token_1.is_cancelled());
|
|
|
|
assert_eq!(
|
|
Poll::Ready(()),
|
|
child_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
assert_eq!(
|
|
Poll::Pending,
|
|
parent_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
|
|
let child_token_2 = token.child_token();
|
|
let child_fut_2 = child_token_2.cancelled();
|
|
pin!(child_fut_2);
|
|
|
|
assert_eq!(
|
|
Poll::Pending,
|
|
child_fut_2.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
assert_eq!(
|
|
Poll::Pending,
|
|
parent_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
|
|
token.cancel();
|
|
assert_eq!(wake_counter, 3);
|
|
assert_eq!(true, token.is_cancelled());
|
|
assert_eq!(true, child_token_2.is_cancelled());
|
|
|
|
assert_eq!(
|
|
Poll::Ready(()),
|
|
child_fut_2.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
assert_eq!(
|
|
Poll::Ready(()),
|
|
parent_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn create_child_token_after_parent_was_cancelled() {
|
|
for drop_child_first in [true, false].iter().cloned() {
|
|
let (waker, wake_counter) = new_count_waker();
|
|
let token = CancellationToken::new();
|
|
token.cancel();
|
|
|
|
let child_token = token.child_token();
|
|
assert!(child_token.is_cancelled());
|
|
|
|
{
|
|
let child_fut = child_token.cancelled();
|
|
pin!(child_fut);
|
|
let parent_fut = token.cancelled();
|
|
pin!(parent_fut);
|
|
|
|
assert_eq!(
|
|
Poll::Ready(()),
|
|
child_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
assert_eq!(
|
|
Poll::Ready(()),
|
|
parent_fut.as_mut().poll(&mut Context::from_waker(&waker))
|
|
);
|
|
assert_eq!(wake_counter, 0);
|
|
|
|
drop(child_fut);
|
|
drop(parent_fut);
|
|
}
|
|
|
|
if drop_child_first {
|
|
drop(child_token);
|
|
drop(token);
|
|
} else {
|
|
drop(token);
|
|
drop(child_token);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn drop_multiple_child_tokens() {
|
|
for drop_first_child_first in &[true, false] {
|
|
let token = CancellationToken::new();
|
|
let mut child_tokens = [None, None, None];
|
|
for child in &mut child_tokens {
|
|
*child = Some(token.child_token());
|
|
}
|
|
|
|
assert!(!token.is_cancelled());
|
|
assert!(!child_tokens[0].as_ref().unwrap().is_cancelled());
|
|
|
|
for i in 0..child_tokens.len() {
|
|
if *drop_first_child_first {
|
|
child_tokens[i] = None;
|
|
} else {
|
|
child_tokens[child_tokens.len() - 1 - i] = None;
|
|
}
|
|
assert!(!token.is_cancelled());
|
|
}
|
|
|
|
drop(token);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn drop_parent_before_child_tokens() {
|
|
let token = CancellationToken::new();
|
|
let child1 = token.child_token();
|
|
let child2 = token.child_token();
|
|
|
|
drop(token);
|
|
assert!(!child1.is_cancelled());
|
|
|
|
drop(child1);
|
|
drop(child2);
|
|
}
|