use std::sync::Arc as StdArc;
use teksilo_canvas::sync::{Arc, AtomicBool, Ordering, model, thread};
use super::{RequestRedraw, WindowWakeTarget};
struct Watched {
disconnected: Arc<AtomicBool>,
dropped: Arc<AtomicBool>,
}
impl RequestRedraw for Watched {
fn request_redraw(&self) {
assert!(
!self.disconnected.load(Ordering::Acquire),
"a redraw was asked of a window after disconnect returned"
);
}
}
impl Drop for Watched {
fn drop(&mut self) {
self.dropped.store(true, Ordering::Release);
}
}
#[test]
fn loom_disconnect_vs_wake() {
model(|| {
let disconnected = Arc::new(AtomicBool::new(false));
let dropped = Arc::new(AtomicBool::new(false));
let target = WindowWakeTarget::new(StdArc::new(Watched {
disconnected: disconnected.clone(),
dropped: dropped.clone(),
}));
let producer = {
let target = target.clone();
thread::spawn(move || target.wake_draw())
};
target.disconnect();
assert!(
dropped.load(Ordering::Acquire),
"disconnect returned with the window still referenced"
);
disconnected.store(true, Ordering::Release);
producer.join().unwrap();
});
}