1use crate::rt;
2
3use std::ops;
4use std::sync::{LockResult, TryLockError, TryLockResult};
5
6#[derive(Debug)]
8pub struct Mutex<T: ?Sized> {
9 object: rt::Mutex,
10 data: std::sync::Mutex<T>,
11}
12
13#[derive(Debug)]
15pub struct MutexGuard<'a, T: ?Sized> {
16 lock: &'a Mutex<T>,
17 data: Option<std::sync::MutexGuard<'a, T>>,
18}
19
20impl<T> Mutex<T> {
21 pub fn new(data: T) -> Mutex<T> {
23 Mutex {
24 data: std::sync::Mutex::new(data),
25 object: rt::Mutex::new(true),
26 }
27 }
28
29 pub fn into_inner(self) -> LockResult<T> {
31 Ok(self.data.into_inner().unwrap())
32 }
33}
34
35impl<T: ?Sized> Mutex<T> {
36 #[track_caller]
38 pub fn lock(&self) -> LockResult<MutexGuard<'_, T>> {
39 self.object.acquire_lock(location!());
40
41 Ok(MutexGuard {
42 lock: self,
43 data: Some(self.data.lock().unwrap()),
44 })
45 }
46
47 #[track_caller]
55 pub fn try_lock(&self) -> TryLockResult<MutexGuard<'_, T>> {
56 if self.object.try_acquire_lock(location!()) {
57 Ok(MutexGuard {
58 lock: self,
59 data: Some(self.data.lock().unwrap()),
60 })
61 } else {
62 Err(TryLockError::WouldBlock)
63 }
64 }
65
66 pub fn get_mut(&mut self) -> LockResult<&mut T> {
68 Ok(self.data.get_mut().unwrap())
69 }
70}
71
72impl<T: ?Sized + Default> Default for Mutex<T> {
73 fn default() -> Self {
75 Self::new(Default::default())
76 }
77}
78
79impl<T> From<T> for Mutex<T> {
80 fn from(t: T) -> Self {
83 Self::new(t)
84 }
85}
86
87impl<'a, T: ?Sized + 'a> MutexGuard<'a, T> {
88 pub(super) fn unborrow(&mut self) {
89 self.data = None;
90 }
91
92 pub(super) fn reborrow(&mut self) {
93 self.data = Some(self.lock.data.lock().unwrap());
94 }
95
96 pub(super) fn rt(&self) -> &rt::Mutex {
97 &self.lock.object
98 }
99}
100
101impl<'a, T: ?Sized> ops::Deref for MutexGuard<'a, T> {
102 type Target = T;
103
104 fn deref(&self) -> &T {
105 self.data.as_ref().unwrap().deref()
106 }
107}
108
109impl<'a, T: ?Sized> ops::DerefMut for MutexGuard<'a, T> {
110 fn deref_mut(&mut self) -> &mut T {
111 self.data.as_mut().unwrap().deref_mut()
112 }
113}
114
115impl<'a, T: ?Sized + 'a> Drop for MutexGuard<'a, T> {
116 fn drop(&mut self) {
117 self.data = None;
118 self.lock.object.release_lock();
119 }
120}