This commit is contained in:
Janis 2025-07-06 15:04:58 +02:00
parent 568d14aa9c
commit b22254cb32

View file

@ -357,7 +357,8 @@ pub mod channel {
} }
/// Takes the value from the channel, if it is present. /// Takes the value from the channel, if it is present.
fn take(&mut self) -> Option<T> { /// this function must only ever return `Some` once.
unsafe fn take(&mut self) -> Option<T> {
// unset the OCCUPIED_BIT to indicate that we are taking the value, if any is present. // unset the OCCUPIED_BIT to indicate that we are taking the value, if any is present.
if self if self
.0 .0
@ -369,13 +370,19 @@ pub mod channel {
// The channel was empty, so we return None. // The channel was empty, so we return None.
None None
} else { } else {
// SAFETY: we only ever access this field by pointer
// the OCCUPIED_BIT was set, so we can safely read the value.
// this function is only called once, within `recv`,
// guaranteeing that the value will only be dropped once.
unsafe { Some(self.0.val.get().read().assume_init_read()) } unsafe { Some(self.0.val.get().read().assume_init_read()) }
} }
} }
pub fn recv(mut self) -> T { pub fn recv(mut self) -> T {
loop { loop {
if let Some(t) = self.take() { // SAFETY: recv can only be called once, since it takes ownership of `self`.
// if `take` returns a value, it will never be called again.
if let Some(t) = unsafe { self.take() } {
return t; return t;
} }