Skip to content

Commit 703652b

Browse files
committed
zephyr: sync: channel: Pin the bounded message slots
Although this is a private field and never accessed within this code, explicitly mark it as `Pin` to make it clear that it is important that the data never be moved. Signed-off-by: David Brown <[email protected]>
1 parent 20ee406 commit 703652b

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

zephyr/src/sync/channel.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ use core::ffi::c_void;
4747
use core::fmt;
4848
use core::marker::PhantomData;
4949
use core::mem::MaybeUninit;
50+
use core::pin::Pin;
5051

5152
use crate::sys::queue::Queue;
5253
use crate::time::{Forever, NoWait, Timeout};
@@ -404,6 +405,8 @@ type Slot<T> = UnsafeCell<MaybeUninit<Message<T>>>;
404405
// SAFETY: A Bounded channel contains an array of messages that are allocated together in a Box.
405406
// This Box is held for an eventual future implementation that is able to free the messages, once
406407
// they have all been taken from Zephyr's knowledge. For now, they could also be leaked.
408+
// It is a `Pin<Box<...>>` because it is important that the data never be moved, as we maintain
409+
// pointers to the items in Zephyr queues.
407410
//
408411
// There are two `Queue`s used here: `free` is the free list of messages that are not being sent,
409412
// and `chan` for messages that have been sent but not received. Initially, all slots are placed on
@@ -422,7 +425,7 @@ struct Bounded<T> {
422425
///
423426
/// The UnsafeCell is needed to indicate that this data is handled outside of what Rust is aware
424427
/// of. MaybeUninit allows us to create this without allocation.
425-
_slots: Box<[Slot<T>]>,
428+
_slots: Pin<Box<[Slot<T>]>>,
426429
/// The free queue, holds messages that aren't be used.
427430
free: Queue,
428431
/// The channel queue. These are messages that have been sent and are waiting to be received.
@@ -436,12 +439,13 @@ impl<T> Bounded<T> {
436439
UnsafeCell::new(MaybeUninit::uninit())
437440
})
438441
.collect();
442+
let slots = Box::into_pin(slots);
439443

440444
let free = Queue::new().unwrap();
441445
let chan = Queue::new().unwrap();
442446

443447
// Add each of the boxes to the free list.
444-
for slot in &slots {
448+
for slot in slots.as_ref().iter() {
445449
// SAFETY: See safety discussion on `Bounded`.
446450
unsafe {
447451
free.send(slot.get() as *mut c_void);

0 commit comments

Comments
 (0)