#![cfg(feature = "loom")]
use lite_sync::spsc::channel;
use loom::future::block_on;
use loom::thread;
use std::num::NonZeroUsize;
#[test]
fn loom_spsc_simple_send_recv() {
loom::model(|| {
let (tx, rx) = channel::<usize, 4>(NonZeroUsize::new(2).unwrap());
thread::spawn(move || {
block_on(async move {
tx.send(1).await.unwrap();
tx.send(2).await.unwrap();
});
});
block_on(async move {
assert_eq!(rx.recv().await.unwrap(), 1);
assert_eq!(rx.recv().await.unwrap(), 2);
});
});
}
#[test]
fn loom_spsc_backpressure() {
loom::model(|| {
let (tx, rx) = channel::<usize, 4>(NonZeroUsize::new(1).unwrap());
let tx_thread = thread::spawn(move || {
block_on(async move {
tx.send(1).await.unwrap();
tx.send(2).await.unwrap();
});
});
block_on(async move {
let v1 = rx.recv().await.unwrap();
assert_eq!(v1, 1);
let v2 = rx.recv().await.unwrap();
assert_eq!(v2, 2);
});
tx_thread.join().unwrap();
});
}
#[test]
fn loom_spsc_close_sender() {
loom::model(|| {
let (tx, rx) = channel::<usize, 4>(NonZeroUsize::new(2).unwrap());
thread::spawn(move || {
block_on(async move {
tx.send(100).await.unwrap();
});
});
block_on(async move {
assert_eq!(rx.recv().await.unwrap(), 100);
assert!(rx.recv().await.is_none());
});
});
}
#[test]
fn loom_spsc_close_receiver() {
loom::model(|| {
let (tx, rx) = channel::<usize, 4>(NonZeroUsize::new(1).unwrap());
tx.try_send(1).unwrap();
let tx_thread = thread::spawn(move || {
block_on(async move {
assert!(tx.send(2).await.is_err());
});
});
thread::yield_now();
drop(rx);
tx_thread.join().unwrap();
});
}