1use std::{cell::UnsafeCell, marker::PhantomData, ops::Deref, ops::DerefMut};
2
3use lock_api::RawMutex as Unused0;
4use parking_lot::RawMutex;
5
6use crate::{LockInfo, RawLockGuard, ReadLock, WriteLock};
7
8pub fn new_mutex<T>(data: T, id: usize) -> Mutex<T> {
9 Mutex {
10 data: UnsafeCell::new(data),
11 id,
12 raw: RawMutex::INIT,
13 }
14}
15
16pub struct Mutex<T> {
17 data: UnsafeCell<T>,
18 id: usize,
19 raw: RawMutex,
20}
21
22impl<T> Mutex<T> {
23 pub fn lock_id(&self) -> usize {
24 self.id
25 }
26
27 pub unsafe fn raw(&self) -> &RawMutex {
45 &self.raw
46 }
47
48 pub unsafe fn acquire_guard(&self) -> MutexGuard<'_, T> {
49 MutexGuard {
50 marker: PhantomData,
51 mutex: self,
52 }
53 }
54}
55
56impl<'a, T> ReadLock<'a> for &'a Mutex<T>
57where
58 T: 'a,
59{
60 type Output = MutexGuard<'a, T>;
61
62 unsafe fn lock_info(&self) -> LockInfo<'_> {
63 LockInfo {
64 id: self.lock_id(),
65 guard: RawLockGuard::RawMutex(self.raw()),
66 }
67 }
68
69 unsafe fn lock_unchecked(self) -> <Self as ReadLock<'a>>::Output {
70 self.acquire_guard()
71 }
72}
73
74impl<'a, T> WriteLock<'a> for &'a Mutex<T>
75where
76 T: 'a,
77{
78 type Output = MutexGuard<'a, T>;
79
80 unsafe fn lock_info(&self) -> LockInfo<'_> {
81 LockInfo {
82 id: self.lock_id(),
83 guard: RawLockGuard::RawMutex(self.raw()),
84 }
85 }
86
87 unsafe fn lock_unchecked(self) -> <Self as WriteLock<'a>>::Output {
88 self.acquire_guard()
89 }
90}
91
92pub struct MutexGuard<'a, T> {
93 marker: PhantomData<(&'a mut T, *mut ())>,
94 mutex: &'a Mutex<T>,
95}
96
97impl<T> Deref for MutexGuard<'_, T> {
98 type Target = T;
99
100 fn deref(&self) -> &<Self as Deref>::Target {
101 unsafe { &*self.mutex.data.get() }
102 }
103}
104
105impl<T> DerefMut for MutexGuard<'_, T> {
106 fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
107 unsafe { &mut *self.mutex.data.get() }
108 }
109}
110
111impl<T> Drop for MutexGuard<'_, T> {
112 fn drop(&mut self) {
113 self.mutex.raw.unlock();
114 }
115}