use jobserver::Client; use std::sync::atomic::*; use std::sync::mpsc; use std::sync::*; macro_rules! t { ($e:expr) => { match $e { Ok(e) => e, Err(e) => panic!("{} failed with {}", stringify!($e), e), } }; } #[test] fn helper_smoke() { let client = t!(Client::new(1)); drop(client.clone().into_helper_thread(|_| ()).unwrap()); drop(client.clone().into_helper_thread(|_| ()).unwrap()); drop(client.clone().into_helper_thread(|_| ()).unwrap()); drop(client.clone().into_helper_thread(|_| ()).unwrap()); drop(client.clone().into_helper_thread(|_| ()).unwrap()); drop(client.into_helper_thread(|_| ()).unwrap()); } #[test] fn acquire() { let (tx, rx) = mpsc::channel(); let client = t!(Client::new(1)); let helper = client .into_helper_thread(move |a| drop(tx.send(a))) .unwrap(); assert!(rx.try_recv().is_err()); helper.request_token(); rx.recv().unwrap().unwrap(); helper.request_token(); rx.recv().unwrap().unwrap(); helper.request_token(); helper.request_token(); rx.recv().unwrap().unwrap(); rx.recv().unwrap().unwrap(); helper.request_token(); helper.request_token(); drop(helper); } #[test] fn prompt_shutdown() { for _ in 0..100 { let client = jobserver::Client::new(4).unwrap(); let count = Arc::new(AtomicU32::new(0)); let count2 = count.clone(); let tokens = Arc::new(Mutex::new(Vec::new())); let helper = client .into_helper_thread(move |token| { tokens.lock().unwrap().push(token); count2.fetch_add(1, Ordering::SeqCst); }) .unwrap(); // Request more tokens than what are available. for _ in 0..5 { helper.request_token(); } // Wait for at least some of the requests to finish. while count.load(Ordering::SeqCst) < 3 { std::thread::yield_now(); } // Drop helper let t = std::time::Instant::now(); drop(helper); let d = t.elapsed(); assert!(d.as_secs_f64() < 0.5); } }