From 91c43f19b2b9e8adba6020f1ed1ab446018f29ca Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Tue, 21 Oct 2025 11:13:29 -0700 Subject: [PATCH] test(semaphore): loom test that might reproduce a deadlock idk --- tokio/src/sync/tests/loom_semaphore_batch.rs | 51 ++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tokio/src/sync/tests/loom_semaphore_batch.rs b/tokio/src/sync/tests/loom_semaphore_batch.rs index 27a459521..c1151fa13 100644 --- a/tokio/src/sync/tests/loom_semaphore_batch.rs +++ b/tokio/src/sync/tests/loom_semaphore_batch.rs @@ -47,6 +47,57 @@ fn basic_usage() { }); } +#[test] +fn cap_one() { + const NUM: usize = 4; + + struct Shared { + semaphore: Semaphore, + } + + async fn actor(shared: Arc, n: usize) { + use futures::FutureExt; + let mut the_acquire = Some(Box::pin(shared.semaphore.acquire(1))); + poll_fn(|cx| match the_acquire.take() { + Some(mut acquire) => match acquire.poll_unpin(cx) { + Poll::Ready(Ok(_)) => Poll::Ready(()), + Poll::Ready(Err(_)) => Poll::Ready(()), + Poll::Pending if n % 2 == 0 => { + the_acquire = Some(acquire); + Poll::Pending + } + Poll::Pending => Poll::Pending, + }, + None => Poll::Ready(()), + }) + .await; + + shared.semaphore.release(1); + } + + static ITERS: std::sync::atomic::AtomicUsize = std::sync::atomic::AtomicUsize::new(0); + loom::model(|| { + dbg!(ITERS.fetch_add(1, std::sync::atomic::Ordering::Relaxed)); + let shared = Arc::new(Shared { + semaphore: Semaphore::new(1), + }); + let mut tasks = Vec::new(); + for n in 0..NUM { + let shared = shared.clone(); + + let th = thread::spawn(move || { + block_on(actor(shared, n)); + }); + tasks.push(th); + } + + // block_on(actor(shared)); + for task in tasks { + task.join().unwrap(); + } + }); +} + #[test] fn release() { loom::model(|| {