leodos_libcfs/os/
queue.rs1use crate::error::{CfsError, OsalError, Result};
8use crate::ffi;
9use crate::os::id::OsalId;
10use crate::os::util::c_name_from_str;
11use crate::string_from_c_buf;
12use crate::status::check;
13use core::marker::PhantomData;
14use core::mem::{self, MaybeUninit};
15use core::ops::Drop;
16use heapless::String;
17
18#[derive(Debug, Clone)]
20pub struct QueueProp {
21 pub name: String<{ ffi::OS_MAX_API_NAME as usize }>,
23 pub creator: OsalId,
25}
26
27#[derive(Debug)]
32pub struct Queue<T: Copy + Sized> {
33 id: OsalId,
34 _phantom: PhantomData<T>,
35}
36
37impl<T: Copy + Sized> Queue<T> {
38 pub fn new(name: &str, depth: usize) -> Result<Self> {
44 let c_name = c_name_from_str(name)?;
45 let mut queue_id = MaybeUninit::uninit();
46
47 let status = unsafe {
48 ffi::OS_QueueCreate(
49 queue_id.as_mut_ptr(),
50 c_name.as_ptr(),
51 depth,
52 mem::size_of::<T>(),
53 0,
54 )
55 };
56 check(status)?;
57
58 Ok(Self {
59 id: OsalId(unsafe { queue_id.assume_init() }),
60 _phantom: PhantomData,
61 })
62 }
63
64 pub fn put(&self, message: &T) -> Result<()> {
71 let status = unsafe {
72 ffi::OS_QueuePut(
73 self.id.0,
74 message as *const T as *const _,
75 mem::size_of::<T>(),
76 0,
77 )
78 };
79 check(status)?;
80 Ok(())
81 }
82
83 pub fn get(&self, timeout_ms: i32) -> Result<T> {
92 let mut message = MaybeUninit::<T>::uninit();
93 let mut size_copied = MaybeUninit::uninit();
94
95 let status = unsafe {
96 ffi::OS_QueueGet(
97 self.id.0,
98 message.as_mut_ptr() as *mut _,
99 mem::size_of::<T>(),
100 size_copied.as_mut_ptr(),
101 timeout_ms,
102 )
103 };
104 check(status)?;
105
106 let size_copied = unsafe { size_copied.assume_init() };
107 if size_copied != mem::size_of::<T>() {
108 return Err(CfsError::Osal(OsalError::QueueInvalidSize));
109 }
110
111 Ok(unsafe { message.assume_init() })
112 }
113
114 pub fn id(&self) -> OsalId {
116 self.id
117 }
118
119 pub fn get_id_by_name(name: &str) -> Result<OsalId> {
121 let c_name = c_name_from_str(name)?;
122 let mut queue_id = MaybeUninit::uninit();
123 check(unsafe { ffi::OS_QueueGetIdByName(queue_id.as_mut_ptr(), c_name.as_ptr()) })?;
124 Ok(OsalId(unsafe { queue_id.assume_init() }))
125 }
126
127 pub fn get_info(&self) -> Result<QueueProp> {
129 let mut prop = MaybeUninit::<ffi::OS_queue_prop_t>::uninit();
130 check(unsafe { ffi::OS_QueueGetInfo(self.id.0, prop.as_mut_ptr()) })?;
131 let prop = unsafe { prop.assume_init() };
132
133 Ok(QueueProp {
134 name: string_from_c_buf(&prop.name)?,
135 creator: OsalId(prop.creator),
136 })
137 }
138}
139
140impl<T: Copy + Sized> Drop for Queue<T> {
141 fn drop(&mut self) {
143 let _ = unsafe { ffi::OS_QueueDelete(self.id.0) };
144 }
145}