summaryrefslogtreecommitdiff
path: root/components/rust/core/src/queue.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/rust/core/src/queue.rs')
-rw-r--r--components/rust/core/src/queue.rs111
1 files changed, 111 insertions, 0 deletions
diff --git a/components/rust/core/src/queue.rs b/components/rust/core/src/queue.rs
new file mode 100644
index 0000000000..82ae43cc54
--- /dev/null
+++ b/components/rust/core/src/queue.rs
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2006-2025, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2025-10-10 foxglove RT-Thread Queue implementation
+ */
+
+use crate::api::*;
+use crate::{panic::panic_on_atomic_context, RTTError};
+use core::cell::UnsafeCell;
+use core::marker::PhantomData;
+use core::mem::{size_of, MaybeUninit};
+use core::ffi::c_void;
+
+const RT_WAITING_FOREVER: isize = -1;
+
+unsafe impl<T> Send for Queue<T> where T: Send {}
+unsafe impl<T> Sync for Queue<T> where T: Send {}
+
+#[derive(Debug)]
+pub struct Queue<T> {
+ queue: APIRawQueue,
+ item_type: PhantomData<UnsafeCell<T>>,
+}
+
+impl<T> Queue<T> {
+ pub fn new(max_size: usize) -> Result<Queue<T>, RTTError> {
+ queue_create("Unnamed", max_size as _, size_of::<T>() as _)
+ .ok_or(RTTError::OutOfMemory)
+ .map(|m| Queue {
+ queue: m,
+ item_type: PhantomData,
+ })
+ }
+
+ pub fn new_with_name(name: &str, max_size: usize) -> Result<Queue<T>, RTTError> {
+ queue_create(name, max_size as _, size_of::<T>() as _)
+ .ok_or(RTTError::OutOfMemory)
+ .map(|m| Queue {
+ queue: m,
+ item_type: PhantomData,
+ })
+ }
+
+ pub fn try_send(&self, item: T) -> Result<(), (RTTError, T)> {
+ self._send(item, 0)
+ }
+
+ pub fn send(&self, item: T, max_wait: i32) -> Result<(), (RTTError, T)> {
+ panic_on_atomic_context("send");
+ self._send(item, max_wait)
+ }
+
+ pub fn send_wait_forever(&self, item: T) -> Result<(), (RTTError, T)> {
+ panic_on_atomic_context("send_wait_forever");
+ self._send(item, RT_WAITING_FOREVER as _)
+ }
+
+ fn _send(&self, item: T, max_wait: i32) -> Result<(), (RTTError, T)> {
+ let inner = MaybeUninit::new(item);
+ let ret = queue_send_wait(
+ self.queue,
+ inner.as_ptr() as *const c_void,
+ size_of::<T>() as _,
+ max_wait,
+ );
+ return if !is_eok(ret) {
+ unsafe { Err((RTTError::QueueSendTimeout, inner.assume_init())) }
+ } else {
+ Ok(())
+ };
+ }
+
+ pub fn try_recv(&self) -> Result<T, RTTError> {
+ self._receive(0)
+ }
+
+ pub fn recv(&self, max_wait: i32) -> Result<T, RTTError> {
+ panic_on_atomic_context("recv");
+ self._receive(max_wait)
+ }
+
+ pub fn recv_wait_forever(&self) -> Result<T, RTTError> {
+ panic_on_atomic_context("recv_wait_forever");
+ self._receive(RT_WAITING_FOREVER as _)
+ }
+
+ fn _receive(&self, max_wait: i32) -> Result<T, RTTError> {
+ let mut inner = MaybeUninit::<T>::uninit();
+ let ret = queue_receive_wait(
+ self.queue,
+ inner.as_mut_ptr() as *mut c_void,
+ size_of::<T>() as _,
+ max_wait,
+ );
+ return if is_eok(ret) {
+ Ok(unsafe { inner.assume_init() })
+ } else {
+ Err(RTTError::QueueReceiveTimeout)
+ };
+ }
+}
+
+impl<T> Drop for Queue<T> {
+ fn drop(&mut self) {
+ queue_delete(self.queue);
+ }
+} \ No newline at end of file