Skip to content

Commit 813a910

Browse files
committed
rtic-sync: add loom tests
1 parent 94eaa79 commit 813a910

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

rtic-sync/src/channel.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,3 +822,57 @@ mod tokio_tests {
822822
}
823823
}
824824
}
825+
826+
#[cfg(test)]
827+
#[cfg(loom)]
828+
mod loom_test {
829+
use cassette::Cassette;
830+
use loom::thread;
831+
832+
#[macro_export]
833+
#[allow(missing_docs)]
834+
macro_rules! make_loom_channel {
835+
($type:ty, $size:expr) => {{
836+
let channel: crate::channel::Channel<$type, $size> = super::Channel::new();
837+
let boxed = Box::new(channel);
838+
let boxed = Box::leak(boxed);
839+
840+
// SAFETY: This is safe as we hide the static mut from others to access it.
841+
// Only this point is where the mutable access happens.
842+
boxed.split()
843+
}};
844+
}
845+
846+
// This test tests the following scenarios:
847+
// 1. Receiver is dropped while concurrent senders are waiting to send.
848+
// 2. Concurrent senders are competing for the same free slot.
849+
#[test]
850+
pub fn concurrent_send_while_full_and_drop() {
851+
loom::model(|| {
852+
let (mut tx, mut rx) = make_loom_channel!([u8; 20], 1);
853+
let mut cloned = tx.clone();
854+
855+
tx.try_send([1; 20]).unwrap();
856+
857+
let handle1 = thread::spawn(move || {
858+
let future = std::pin::pin!(tx.send([1; 20]));
859+
let mut future = Cassette::new(future);
860+
if future.poll_on().is_none() {
861+
future.poll_on();
862+
}
863+
});
864+
865+
rx.try_recv().ok();
866+
867+
let future = std::pin::pin!(cloned.send([1; 20]));
868+
let mut future = Cassette::new(future);
869+
if future.poll_on().is_none() {
870+
future.poll_on();
871+
}
872+
873+
drop(rx);
874+
875+
handle1.join().unwrap();
876+
});
877+
}
878+
}

0 commit comments

Comments
 (0)