use comn::atomic::AtomicN; use comn::syna; use std::{sync, sync::atomic::Ordering, thread, time::Duration}; #[tokio::main] #[test] async fn tokio_main() { struct wrapper { mutx: syna::Autex, cond: syna::Cond, } let aux0 = std::sync::Arc::new(wrapper { mutx: syna::Autex::new(), cond: syna::Cond::new(), }); let aux = aux0.clone(); let f1 = async move { let g = aux.mutx.lock().await; println!( "1, {:?}\t\t hold lock for 2 seconds", thread::current().id() ); tokio::time::sleep(Duration::from_secs(2)).await; println!( "1, {:?}\t\t 2 seconds elapsed, unlock and wait for signal", thread::current().id() ); let g = aux.cond.wait(g).await; println!("1, {:?} condition get signaled", thread::current().id()); thread::sleep_ms(5000); drop(g); }; let aux = aux0.clone(); let f2 = async move { println!("2, {:?}\t\t try getting lock ...", thread::current().id()); let g = aux.mutx.lock().await; println!( "2, {:?}\t\t got lock, wait for signal", thread::current().id() ); let g = aux.cond.wait(g).await; println!("2, {:?} condition get signaled", thread::current().id()); thread::sleep_ms(5000); drop(g); }; let aux = aux0.clone(); let f3 = async move { println!("3, {:?}\t\t try getting lock ...", thread::current().id()); let g = aux.mutx.lock().await; println!( "3, {:?}\t\t got lock, wait for signal", thread::current().id() ); let g = aux.cond.wait(g).await; println!("3, {:?} condition get signaled", thread::current().id()); thread::sleep_ms(5000); drop(g); }; let h1 = tokio::spawn(f1); let h2 = tokio::spawn(f2); let h3 = tokio::spawn(f3); thread::sleep_ms(3000); println!("wakeup condition"); aux0.cond.notify_all().await; tokio::join!(h1, h2, h3); } #[tokio::main] #[test] async fn async_single_flight() { let mut handles = vec![]; let ll = sync::Arc::new(syna::LeadLock::::new()); let n = sync::Arc::new(0); for _ in 0..8000 { let cloned = ll.clone(); let n0 = n.clone(); let h = tokio::spawn(async move { let n1 = cloned .single_flight(async move { tokio::time::sleep(Duration::from_millis(0)).await; sync::Arc::new(n0.atomic_fetch_add(1, Ordering::Relaxed)) }) .await; println!("{:?}\t\t{}", thread::current().id(), n1); }); handles.push(h); } println!("join handles"); while handles.len() > 0 { handles.pop().unwrap().await.unwrap(); } }