emerald_std/sync/spin/
mutex.rs1use core::{
2 cell::UnsafeCell,
3 fmt,
4 marker::PhantomData,
5 ops::{Deref, DerefMut},
6};
7
8use super::lock;
9
10pub struct Mutex<T: ?Sized> {
11 lock: lock::Lock,
12 data: UnsafeCell<T>,
13}
14
15unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
16unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
17
18impl<T> fmt::Debug for Mutex<T>
19where
20 T: fmt::Debug,
21{
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 let mut s = f.debug_struct("Mutex");
24 if let Some(data) = self.try_lock() {
25 s.field("data", &data);
26 } else {
27 s.field("data", &"[locked]");
28 }
29 s.finish()
30 }
31}
32
33#[must_use]
34pub struct MutexGuard<'a, T: ?Sized> {
35 lock: &'a Mutex<T>,
36 marker: PhantomData<*const ()>, }
38
39unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
40
41impl<T> fmt::Debug for MutexGuard<'_, T>
42where
43 T: fmt::Debug,
44{
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 self.deref().fmt(f)
47 }
48}
49
50impl<T> Mutex<T> {
51 pub const fn new(data: T) -> Self {
52 Self {
53 lock: lock::Lock::new(),
54 data: UnsafeCell::new(data),
55 }
56 }
57
58 pub fn lock(&self) -> MutexGuard<'_, T> {
59 self.lock.lock();
61 MutexGuard {
62 lock: self,
63 marker: PhantomData,
64 }
65 }
66
67 pub fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
68 if self.lock.try_lock() {
69 Some(MutexGuard {
70 lock: self,
71 marker: PhantomData,
72 })
73 } else {
74 None
75 }
76 }
77}
78
79impl<T> Deref for MutexGuard<'_, T> {
80 type Target = T;
81
82 fn deref(&self) -> &Self::Target {
83 unsafe { self.lock.data.get().as_ref().unwrap() }
86 }
87}
88
89impl<T> DerefMut for MutexGuard<'_, T> {
90 fn deref_mut(&mut self) -> &mut Self::Target {
91 unsafe { self.lock.data.get().as_mut().unwrap() }
94 }
95}
96
97impl<T: ?Sized> Drop for MutexGuard<'_, T> {
98 fn drop(&mut self) {
99 unsafe { self.lock.lock.unlock() };
101 }
102}