Skip to content

Commit eb636db

Browse files
committed
rtic-sync: add test validating that free queue slots are not lost on drop
1 parent 9a8e265 commit eb636db

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

rtic-sync/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ embedded-hal-bus = { version = "0.2.0", features = ["async"] }
2929
defmt-03 = { package = "defmt", version = "0.3", optional = true }
3030

3131
[dev-dependencies]
32+
cassette = "0.3.0"
3233
static_cell = "2.1.0"
3334
tokio = { version = "1", features = ["rt", "macros", "time"] }
3435

rtic-sync/src/channel.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,8 @@ impl<T, const N: usize> Drop for Receiver<'_, T, N> {
559559

560560
#[cfg(test)]
561561
mod tests {
562+
use cassette::Cassette;
563+
562564
use super::*;
563565

564566
#[test]
@@ -684,4 +686,43 @@ mod tests {
684686
fn tuple_channel() {
685687
let _ = make_channel!((i32, u32), 10);
686688
}
689+
690+
fn freeq<const N: usize, T, F, R>(channel: &Channel<T, N>, f: F) -> R
691+
where
692+
F: FnOnce(&mut Deque<u8, N>) -> R,
693+
{
694+
critical_section::with(|cs| f(channel.access(cs).freeq))
695+
}
696+
697+
#[test]
698+
fn dropping_waked_send_returns_freeq_item() {
699+
let (mut tx, mut rx) = make_channel!(u8, 1);
700+
701+
tx.try_send(0).unwrap();
702+
assert!(freeq(&rx.0, |q| q.is_empty()));
703+
704+
// Running this in a separate thread scope to ensure that `pinned_future` is dropped fully.
705+
//
706+
// Calling drop explicitly gets hairy because dropping things behind a `Pin` is not easy.
707+
std::thread::scope(|scope| {
708+
scope.spawn(|| {
709+
let pinned_future = core::pin::pin!(tx.send(1));
710+
let mut future = Cassette::new(pinned_future);
711+
712+
future.poll_on();
713+
714+
assert!(freeq(&rx.0, |q| q.is_empty()));
715+
assert!(!rx.0.wait_queue.is_empty());
716+
717+
assert_eq!(rx.try_recv(), Ok(0));
718+
719+
assert!(freeq(&rx.0, |q| q.is_empty()));
720+
});
721+
});
722+
723+
assert!(!freeq(&rx.0, |q| q.is_empty()));
724+
725+
// Make sure that rx & tx are alive until here for good measure.
726+
drop((tx, rx));
727+
}
687728
}

0 commit comments

Comments
 (0)