1 //! A minimal adaption of the `parking_lot` synchronization primitives to the
2 //! equivalent `std::sync` types.
3 //!
4 //! This can be extended to additional types/methods as required.
5 
6 use std::fmt;
7 use std::marker::PhantomData;
8 use std::ops::{Deref, DerefMut};
9 use std::sync::LockResult;
10 use std::time::Duration;
11 
12 // All types in this file are marked with PhantomData to ensure that
13 // parking_lot's send_guard feature does not leak through and affect when Tokio
14 // types are Send.
15 //
16 // See <https://github.com/tokio-rs/tokio/pull/4359> for more info.
17 
18 // Types that do not need wrapping
19 pub(crate) use parking_lot::WaitTimeoutResult;
20 
21 #[derive(Debug)]
22 pub(crate) struct Mutex<T: ?Sized>(PhantomData<std::sync::Mutex<T>>, parking_lot::Mutex<T>);
23 
24 #[derive(Debug)]
25 pub(crate) struct RwLock<T>(PhantomData<std::sync::RwLock<T>>, parking_lot::RwLock<T>);
26 
27 #[derive(Debug)]
28 pub(crate) struct Condvar(PhantomData<std::sync::Condvar>, parking_lot::Condvar);
29 
30 #[derive(Debug)]
31 pub(crate) struct MutexGuard<'a, T: ?Sized>(
32     PhantomData<std::sync::MutexGuard<'a, T>>,
33     parking_lot::MutexGuard<'a, T>,
34 );
35 
36 #[derive(Debug)]
37 pub(crate) struct RwLockReadGuard<'a, T: ?Sized>(
38     PhantomData<std::sync::RwLockReadGuard<'a, T>>,
39     parking_lot::RwLockReadGuard<'a, T>,
40 );
41 
42 #[derive(Debug)]
43 pub(crate) struct RwLockWriteGuard<'a, T: ?Sized>(
44     PhantomData<std::sync::RwLockWriteGuard<'a, T>>,
45     parking_lot::RwLockWriteGuard<'a, T>,
46 );
47 
48 impl<T> Mutex<T> {
49     #[inline]
new(t: T) -> Mutex<T>50     pub(crate) fn new(t: T) -> Mutex<T> {
51         Mutex(PhantomData, parking_lot::Mutex::new(t))
52     }
53 
54     #[inline]
55     #[cfg(not(all(loom, test)))]
const_new(t: T) -> Mutex<T>56     pub(crate) const fn const_new(t: T) -> Mutex<T> {
57         Mutex(PhantomData, parking_lot::const_mutex(t))
58     }
59 
60     #[inline]
lock(&self) -> MutexGuard<'_, T>61     pub(crate) fn lock(&self) -> MutexGuard<'_, T> {
62         MutexGuard(PhantomData, self.1.lock())
63     }
64 
65     #[inline]
try_lock(&self) -> Option<MutexGuard<'_, T>>66     pub(crate) fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
67         self.1
68             .try_lock()
69             .map(|guard| MutexGuard(PhantomData, guard))
70     }
71 
72     #[inline]
get_mut(&mut self) -> &mut T73     pub(crate) fn get_mut(&mut self) -> &mut T {
74         self.1.get_mut()
75     }
76 
77     // Note: Additional methods `is_poisoned` and `into_inner`, can be
78     // provided here as needed.
79 }
80 
81 impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> {
82     type Target = T;
deref(&self) -> &T83     fn deref(&self) -> &T {
84         self.1.deref()
85     }
86 }
87 
88 impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> {
deref_mut(&mut self) -> &mut T89     fn deref_mut(&mut self) -> &mut T {
90         self.1.deref_mut()
91     }
92 }
93 
94 impl<T> RwLock<T> {
new(t: T) -> RwLock<T>95     pub(crate) fn new(t: T) -> RwLock<T> {
96         RwLock(PhantomData, parking_lot::RwLock::new(t))
97     }
98 
read(&self) -> RwLockReadGuard<'_, T>99     pub(crate) fn read(&self) -> RwLockReadGuard<'_, T> {
100         RwLockReadGuard(PhantomData, self.1.read())
101     }
102 
try_read(&self) -> Option<RwLockReadGuard<'_, T>>103     pub(crate) fn try_read(&self) -> Option<RwLockReadGuard<'_, T>> {
104         Some(RwLockReadGuard(PhantomData, self.1.read()))
105     }
106 
write(&self) -> RwLockWriteGuard<'_, T>107     pub(crate) fn write(&self) -> RwLockWriteGuard<'_, T> {
108         RwLockWriteGuard(PhantomData, self.1.write())
109     }
110 
try_write(&self) -> Option<RwLockWriteGuard<'_, T>>111     pub(crate) fn try_write(&self) -> Option<RwLockWriteGuard<'_, T>> {
112         Some(RwLockWriteGuard(PhantomData, self.1.write()))
113     }
114 }
115 
116 impl<'a, T: ?Sized> Deref for RwLockReadGuard<'a, T> {
117     type Target = T;
deref(&self) -> &T118     fn deref(&self) -> &T {
119         self.1.deref()
120     }
121 }
122 
123 impl<'a, T: ?Sized> Deref for RwLockWriteGuard<'a, T> {
124     type Target = T;
deref(&self) -> &T125     fn deref(&self) -> &T {
126         self.1.deref()
127     }
128 }
129 
130 impl<'a, T: ?Sized> DerefMut for RwLockWriteGuard<'a, T> {
deref_mut(&mut self) -> &mut T131     fn deref_mut(&mut self) -> &mut T {
132         self.1.deref_mut()
133     }
134 }
135 
136 impl Condvar {
137     #[inline]
new() -> Condvar138     pub(crate) fn new() -> Condvar {
139         Condvar(PhantomData, parking_lot::Condvar::new())
140     }
141 
142     #[inline]
notify_one(&self)143     pub(crate) fn notify_one(&self) {
144         self.1.notify_one();
145     }
146 
147     #[inline]
notify_all(&self)148     pub(crate) fn notify_all(&self) {
149         self.1.notify_all();
150     }
151 
152     #[inline]
wait<'a, T>( &self, mut guard: MutexGuard<'a, T>, ) -> LockResult<MutexGuard<'a, T>>153     pub(crate) fn wait<'a, T>(
154         &self,
155         mut guard: MutexGuard<'a, T>,
156     ) -> LockResult<MutexGuard<'a, T>> {
157         self.1.wait(&mut guard.1);
158         Ok(guard)
159     }
160 
161     #[inline]
wait_timeout<'a, T>( &self, mut guard: MutexGuard<'a, T>, timeout: Duration, ) -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)>162     pub(crate) fn wait_timeout<'a, T>(
163         &self,
164         mut guard: MutexGuard<'a, T>,
165         timeout: Duration,
166     ) -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> {
167         let wtr = self.1.wait_for(&mut guard.1, timeout);
168         Ok((guard, wtr))
169     }
170 
171     // Note: Additional methods `wait_timeout_ms`, `wait_timeout_until`,
172     // `wait_until` can be provided here as needed.
173 }
174 
175 impl<'a, T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'a, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result176     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177         fmt::Display::fmt(&self.1, f)
178     }
179 }
180 
181 impl<'a, T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'a, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result182     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183         fmt::Display::fmt(&self.1, f)
184     }
185 }
186 
187 impl<'a, T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'a, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result188     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
189         fmt::Display::fmt(&self.1, f)
190     }
191 }
192