#![cfg(feature = "loom")]
use loom::sync::Arc;
use loom::sync::Mutex;
use loom::sync::mpsc;
use loom::thread;
fn correct_attach(
pre_subscribe_buffer: Arc<Mutex<Vec<u8>>>,
live_emit: Arc<Mutex<Vec<u8>>>,
) -> Vec<u8> {
let (tx, rx) = mpsc::channel::<u8>();
let live_tx = Arc::new(Mutex::new(Some(tx)));
let live_tx_clone = live_tx.clone();
let live_emit_clone = live_emit.clone();
let emit_handle = thread::spawn(move || {
let mut guard = live_tx_clone.lock().unwrap();
if let Some(tx) = guard.take() {
for b in live_emit_clone.lock().unwrap().drain(..) {
let _ = tx.send(b);
}
drop(tx);
}
});
let snapshot: Vec<u8> = pre_subscribe_buffer.lock().unwrap().clone();
let mut live: Vec<u8> = Vec::new();
while let Ok(b) = rx.recv() {
live.push(b);
}
emit_handle.join().unwrap();
let mut observed = snapshot;
observed.extend(live);
observed
}
#[ignore]
#[test]
fn correct_attach_observes_all_bytes_under_all_schedules() {
loom::model(|| {
let pre = Arc::new(Mutex::new(vec![1, 2]));
let live = Arc::new(Mutex::new(vec![3, 4]));
let observed = correct_attach(pre.clone(), live.clone());
for b in [1u8, 2, 3, 4] {
assert!(observed.contains(&b), "missing byte {b} in {observed:?}");
}
});
}