mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-08 00:00:13 +02:00
WIP make loom work in tokio-util
This commit is contained in:
@@ -58,6 +58,9 @@ futures-test = "0.3.5"
|
|||||||
parking_lot = "0.12.0"
|
parking_lot = "0.12.0"
|
||||||
tempfile = "3.1.0"
|
tempfile = "3.1.0"
|
||||||
|
|
||||||
|
[target.'cfg(loom)'.dev-dependencies]
|
||||||
|
loom = { version = "0.5.2", features = ["futures", "checkpoint"] }
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
# enable unstable features in the documentation
|
# enable unstable features in the documentation
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(all(test, not(loom)))]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use tokio::io::{repeat, AsyncReadExt, Repeat};
|
use tokio::io::{repeat, AsyncReadExt, Repeat};
|
||||||
|
|||||||
@@ -1 +1,5 @@
|
|||||||
|
#[cfg(not(loom))]
|
||||||
pub(crate) use std::sync;
|
pub(crate) use std::sync;
|
||||||
|
|
||||||
|
#[cfg(loom)]
|
||||||
|
pub(crate) use loom::sync;
|
||||||
|
|||||||
@@ -298,12 +298,15 @@ pub(crate) fn cancel(node: &Arc<TreeNode>) {
|
|||||||
if locked_node.is_cancelled {
|
if locked_node.is_cancelled {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
println!("a");
|
||||||
|
|
||||||
// One by one, adopt grandchildren and then cancel and detach the child
|
// One by one, adopt grandchildren and then cancel and detach the child
|
||||||
while let Some(child) = locked_node.children.pop() {
|
while let Some(child) = locked_node.children.pop() {
|
||||||
|
println!("b1");
|
||||||
// This can't deadlock because the mutex we are already
|
// This can't deadlock because the mutex we are already
|
||||||
// holding is the parent of child.
|
// holding is the parent of child.
|
||||||
let mut locked_child = child.inner.lock().unwrap();
|
let mut locked_child = child.inner.lock().unwrap();
|
||||||
|
println!("b2");
|
||||||
|
|
||||||
// Detach the child from node
|
// Detach the child from node
|
||||||
// No need to modify node.children, as the child already got removed with `.pop`
|
// No need to modify node.children, as the child already got removed with `.pop`
|
||||||
@@ -356,10 +359,12 @@ pub(crate) fn cancel(node: &Arc<TreeNode>) {
|
|||||||
// Now the child is cancelled and detached and all its children are adopted.
|
// Now the child is cancelled and detached and all its children are adopted.
|
||||||
// Just continue until all (including adopted) children are cancelled and detached.
|
// Just continue until all (including adopted) children are cancelled and detached.
|
||||||
}
|
}
|
||||||
|
println!("c");
|
||||||
|
|
||||||
// Cancel the node itself.
|
// Cancel the node itself.
|
||||||
locked_node.is_cancelled = true;
|
locked_node.is_cancelled = true;
|
||||||
locked_node.children = Vec::new();
|
locked_node.children = Vec::new();
|
||||||
drop(locked_node);
|
drop(locked_node);
|
||||||
node.waker.notify_waiters();
|
node.waker.notify_waiters();
|
||||||
|
println!("d");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,3 +13,6 @@ pub use poll_semaphore::PollSemaphore;
|
|||||||
|
|
||||||
mod reusable_box;
|
mod reusable_box;
|
||||||
pub use reusable_box::ReusableBoxFuture;
|
pub use reusable_box::ReusableBoxFuture;
|
||||||
|
|
||||||
|
#[cfg(loom)]
|
||||||
|
mod tests;
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ fn cancel_token_owned() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn cancel_with_child() {
|
fn cancel_with_child() {
|
||||||
loom::model(|| {
|
loom::model(|| {
|
||||||
|
println!("FOO");
|
||||||
let token = CancellationToken::new();
|
let token = CancellationToken::new();
|
||||||
let token1 = token.clone();
|
let token1 = token.clone();
|
||||||
let token2 = token.clone();
|
let token2 = token.clone();
|
||||||
@@ -153,20 +154,27 @@ fn drop_and_cancel_token() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn cancel_parent_and_child() {
|
fn cancel_parent_and_child() {
|
||||||
loom::model(|| {
|
loom::model(|| {
|
||||||
|
println!("FOO");
|
||||||
let token1 = CancellationToken::new();
|
let token1 = CancellationToken::new();
|
||||||
let token2 = token1.clone();
|
let token2 = token1.clone();
|
||||||
let child_token = token1.child_token();
|
let child_token = token1.child_token();
|
||||||
|
|
||||||
let th1 = thread::spawn(move || {
|
let th1 = thread::spawn(move || {
|
||||||
|
println!("drop parent");
|
||||||
drop(token1);
|
drop(token1);
|
||||||
|
println!("drop parent done");
|
||||||
});
|
});
|
||||||
|
|
||||||
let th2 = thread::spawn(move || {
|
let th2 = thread::spawn(move || {
|
||||||
|
println!("cancel parent");
|
||||||
token2.cancel();
|
token2.cancel();
|
||||||
|
println!("cancel parent done");
|
||||||
});
|
});
|
||||||
|
|
||||||
let th3 = thread::spawn(move || {
|
let th3 = thread::spawn(move || {
|
||||||
|
println!("cancel child");
|
||||||
child_token.cancel();
|
child_token.cancel();
|
||||||
|
println!("cancel child done");
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_ok!(th1.join());
|
assert_ok!(th1.join());
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
|
mod loom_cancellation_token;
|
||||||
|
|||||||
Reference in New Issue
Block a user