#![cfg(feature = "std")] use exclusion_set::Set; extern crate std; use core::any::TypeId; use std::sync::Arc; #[cfg(loom)] use loom::{model, thread}; #[cfg(not(loom))] fn model(f: F) { f(); } #[cfg(not(loom))] use std::thread; #[test] fn two_threads_wait() { model(|| { struct Marker; let set: Arc> = Arc::default(); let set2 = Arc::clone(&set); let other = thread::spawn(move || { set2.wait_to_insert(TypeId::of::()); unsafe { assert!(set2.remove(&TypeId::of::())); } }); set.wait_to_insert(TypeId::of::()); unsafe { assert!(set.remove(&TypeId::of::())); } other.join().unwrap(); }); } #[test] #[ignore = "very slow"] fn three_threads_wait() { model(|| { struct Marker; let set0: Arc> = Arc::default(); let set1 = Arc::clone(&set0); let set2 = Arc::clone(&set0); let thread1 = thread::spawn(move || { set1.wait_to_insert(TypeId::of::()); unsafe { assert!(set1.remove(&TypeId::of::())); } }); let thread2 = thread::spawn(move || { set2.wait_to_insert(TypeId::of::()); unsafe { assert!(set2.remove(&TypeId::of::())); } }); set0.wait_to_insert(TypeId::of::()); unsafe { assert!(set0.remove(&TypeId::of::())); } thread1.join().unwrap(); thread2.join().unwrap(); }); } #[test] fn two_threads_wait_after_an_insert() { model(|| { struct Marker1; struct Marker2; let set: Arc> = Arc::default(); assert!(set.try_insert(TypeId::of::())); let set2 = Arc::clone(&set); let other = thread::spawn(move || { set2.wait_to_insert(TypeId::of::()); unsafe { assert!(set2.remove(&TypeId::of::())); } }); set.wait_to_insert(TypeId::of::()); unsafe { assert!(set.remove(&TypeId::of::())); } other.join().unwrap(); }); } #[test] #[ignore = "very slow"] fn alternating_waits() { model(|| { struct Marker; let typeid_value = TypeId::of::(); let set: Arc> = Arc::default(); assert!(set.try_insert(TypeId::of::())); let set2 = Arc::clone(&set); let other = thread::spawn(move || { set2.wait_to_insert(typeid_value); unsafe { assert!(set2.remove(&typeid_value)); } set2.wait_to_insert(typeid_value); unsafe { assert!(set2.remove(&typeid_value)); } }); unsafe { assert!(set.remove(&typeid_value)); } set.wait_to_insert(typeid_value); unsafe { assert!(set.remove(&typeid_value)); } set.wait_to_insert(typeid_value); unsafe { assert!(set.remove(&typeid_value)); } other.join().unwrap(); }); }