1use core::{
2 cell::UnsafeCell,
3 fmt::{self, Debug, Display, Formatter},
4 ops::{Deref, DerefMut},
5};
6
7use crate::{bindings, error::*};
8
9use super::TIMEOUT_MAX;
10
11pub struct Mutex<T: ?Sized> {
13 mutex: bindings::mutex_t,
14 data: UnsafeCell<T>,
15}
16
17unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
18
19unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
20
21impl<T> Mutex<T> {
23 #[inline]
24 pub fn new(data: T) -> Self {
27 Self::try_new(data).unwrap_or_else(|err| panic!("failed to create mutex: {:?}", err))
28 }
29
30 pub fn try_new(data: T) -> Result<Self, Error> {
32 Ok(Self {
33 data: UnsafeCell::new(data),
34 mutex: unsafe { bindings::mutex_recursive_create() }.check()?,
35 })
36 }
37}
38
39impl<T: ?Sized> Mutex<T> {
40 #[inline]
41 pub fn lock(&'_ self) -> MutexGuard<'_, T> {
56 self.try_lock()
57 .unwrap_or_else(|err| panic!("Failed to lock mutex: {:?}", err))
58 }
59
60 #[inline]
61 pub fn try_lock(&'_ self) -> Result<MutexGuard<'_, T>, Error> {
65 if unsafe { bindings::mutex_recursive_take(self.mutex, TIMEOUT_MAX) } {
66 Ok(MutexGuard(self))
67 } else {
68 Err(from_errno())
69 }
70 }
71
72 #[inline]
73 pub fn poll(&'_ self) -> Option<MutexGuard<'_, T>> {
76 if unsafe { bindings::mutex_recursive_take(self.mutex, 0) } {
77 Some(MutexGuard(self))
78 } else {
79 None
80 }
81 }
82}
83
84impl<T: ?Sized> Drop for Mutex<T> {
85 #[inline]
86 fn drop(&mut self) {
87 unsafe { bindings::mutex_delete(self.mutex) }
88 }
89}
90
91impl<T: ?Sized + Debug> Debug for Mutex<T> {
92 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
93 match self.poll() {
94 Some(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(),
95 None => {
96 struct LockedPlaceholder;
97 impl Debug for LockedPlaceholder {
98 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
99 f.write_str("<locked>")
100 }
101 }
102
103 f.debug_struct("Mutex")
104 .field("data", &LockedPlaceholder)
105 .finish()
106 }
107 }
108 }
109}
110
111impl<T: ?Sized + Default> Default for Mutex<T> {
112 #[inline]
113 fn default() -> Self {
114 Self::new(Default::default())
115 }
116}
117
118impl<T> From<T> for Mutex<T> {
119 #[inline]
120 fn from(data: T) -> Self {
121 Self::new(data)
122 }
123}
124
125pub struct MutexGuard<'a, T: ?Sized>(&'a Mutex<T>);
138
139impl<T: ?Sized> Deref for MutexGuard<'_, T> {
140 type Target = T;
141
142 #[inline]
143 fn deref(&self) -> &Self::Target {
144 unsafe { &*self.0.data.get() }
145 }
146}
147
148impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
149 #[inline]
150 fn deref_mut(&mut self) -> &mut Self::Target {
151 unsafe { &mut *self.0.data.get() }
152 }
153}
154
155impl<T: ?Sized> Drop for MutexGuard<'_, T> {
156 #[inline]
157 fn drop(&mut self) {
158 if !unsafe { bindings::mutex_recursive_give(self.0.mutex) } {
159 panic!("failed to return mutex: {:?}", from_errno());
160 }
161 }
162}
163
164impl<T: ?Sized + Debug> Debug for MutexGuard<'_, T> {
165 #[inline]
166 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
167 Debug::fmt(&**self, f)
168 }
169}
170
171impl<T: ?Sized + Display> Display for MutexGuard<'_, T> {
172 #[inline]
173 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
174 (**self).fmt(f)
175 }
176}
177
178impl<T: ?Sized> !Send for MutexGuard<'_, T> {}
179
180unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}