Skip to content

Commit d4108c0

Browse files
committed
zephyr: sync: channel: Add send timeout and try variants
Add implementations for `try_send` and `send_timeout` to channels. Currently, these all use the same error code, as there is only one kind of failure possible with Zephyr's channels (and zephyr treats "try" as just a zero timeout). Signed-off-by: David Brown <[email protected]>
1 parent 7ac4c94 commit d4108c0

File tree

1 file changed

+31
-5
lines changed

1 file changed

+31
-5
lines changed

zephyr/src/sync/channel.rs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use core::marker::PhantomData;
2222
use core::mem::MaybeUninit;
2323

2424
use crate::sys::queue::Queue;
25-
use crate::time::Forever;
25+
use crate::time::{Forever, NoWait, Timeout};
2626

2727
mod counter;
2828

@@ -118,9 +118,15 @@ unsafe impl<T: Send> Send for Sender<T> {}
118118
unsafe impl<T: Send> Sync for Sender<T> {}
119119

120120
impl<T> Sender<T> {
121-
/// Sends a message over the given channel. This will perform an alloc of the message, which
122-
/// will have an accompanied free on the recipient side.
123-
pub fn send(&self, msg: T) -> Result<(), SendError<T>> {
121+
/// Waits for a message to be sent into the channel, but only for a limited time.
122+
///
123+
/// This call will block until the send operation can proceed or the operation times out.
124+
///
125+
/// For unbounded channels, this will perform an allocation (and always send immediately). For
126+
/// bounded channels, no allocation will be performed.
127+
pub fn send_timeout<D>(&self, msg: T, timeout: D) -> Result<(), SendError<T>>
128+
where D: Into<Timeout>,
129+
{
124130
match &self.flavor {
125131
SenderFlavor::Unbounded { queue, .. } => {
126132
let msg = Box::new(Message::new(msg));
@@ -131,7 +137,10 @@ impl<T> Sender<T> {
131137
}
132138
SenderFlavor::Bounded(chan) => {
133139
// Retrieve a message buffer from the free list.
134-
let buf = unsafe { chan.free.recv(Forever) };
140+
let buf = unsafe { chan.free.recv(timeout) };
141+
if buf.is_null() {
142+
return Err(SendError(msg));
143+
}
135144
let buf = buf as *mut Message<T>;
136145
unsafe {
137146
buf.write(Message::new(msg));
@@ -141,6 +150,23 @@ impl<T> Sender<T> {
141150
}
142151
Ok(())
143152
}
153+
154+
/// Sends a message over the given channel. Waiting if necessary.
155+
///
156+
/// For unbounded channels, this will allocate space for a message, and immediately send it.
157+
/// For bounded channels, this will block until a message slot is available, and then send the
158+
/// message.
159+
pub fn send(&self, msg: T) -> Result<(), SendError<T>> {
160+
self.send_timeout(msg, Forever)
161+
}
162+
163+
/// Attempts to send a message into the channel without blocking.
164+
///
165+
/// This message will either send a message into the channel immediately or return an error if
166+
/// the channel is full. The returned error contains the original message.
167+
pub fn try_send(&self, msg: T) -> Result<(), SendError<T>> {
168+
self.send_timeout(msg, NoWait)
169+
}
144170
}
145171

146172
impl<T> Drop for Sender<T> {

0 commit comments

Comments
 (0)