#![cfg(not(any(miri, loom)))]
use core::{
sync::atomic::{AtomicUsize, Ordering},
time::Duration,
};
use kwokka::{
runtime::Runtime,
task::{scope, yield_now},
time::sleep,
};
static CHILDREN_RAN: AtomicUsize = AtomicUsize::new(0);
#[test]
fn sleep_resolves_scope_joins_children_and_yield_round_trips() {
let Ok(mut runtime) = Runtime::affine() else {
panic!("the affine runtime must build on this host");
};
let (slept, spawned, yielded) = runtime.block_on(async {
sleep(Duration::from_millis(1)).await;
let slept = true;
let spawned = scope(|scope| {
let first = scope
.spawn(async {
sleep(Duration::from_millis(1)).await;
CHILDREN_RAN.fetch_add(1, Ordering::Relaxed);
})
.is_ok();
let second = scope
.spawn(async {
sleep(Duration::from_millis(1)).await;
CHILDREN_RAN.fetch_add(1, Ordering::Relaxed);
})
.is_ok();
first && second
})
.await;
yield_now().await;
let yielded = true;
(slept, spawned, yielded)
});
assert!(slept, "the sleep future resolved past its await");
assert!(spawned, "the scope accepted both children");
assert!(yielded, "yield_now resumed after handing back the worker");
assert_eq!(
CHILDREN_RAN.load(Ordering::Relaxed),
2,
"the scope resolved only after both children ran",
);
}