use std::sync::Arc; use async_std::prelude::*; use async_std::sync::Mutex; use async_std::task; use futures::channel::mpsc; #[cfg(not(target_os = "unknown"))] use async_std::task::spawn; #[cfg(target_os = "unknown")] use async_std::task::spawn_local as spawn; #[cfg(target_arch = "wasm32")] wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn smoke() { task::block_on(async { let m = Mutex::new(()); drop(m.lock().await); drop(m.lock().await); }) } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn try_lock() { let m = Mutex::new(()); *m.try_lock().unwrap() = (); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn into_inner() { let m = Mutex::new(10); assert_eq!(m.into_inner(), 10); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn get_mut() { let mut m = Mutex::new(10); *m.get_mut() = 20; assert_eq!(m.into_inner(), 20); } #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] fn contention() { task::block_on(async { let (tx, mut rx) = mpsc::unbounded(); let tx = Arc::new(tx); let mutex = Arc::new(Mutex::new(0)); let num_tasks = 10000; let mut handles = Vec::new(); for _ in 0..num_tasks { let tx = tx.clone(); let mutex = mutex.clone(); handles.push(spawn(async move { let mut lock = mutex.lock().await; *lock += 1; tx.unbounded_send(()).unwrap(); drop(lock); })); } for _ in 0..num_tasks { rx.next().await.unwrap(); } for handle in handles.into_iter() { handle.await; } dbg!("wait"); let lock = mutex.lock().await; assert_eq!(num_tasks, *lock); }); }