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) -> LockResult<RwLockReadGuard<'_, T>>99 pub(crate) fn read(&self) -> LockResult<RwLockReadGuard<'_, T>> { 100 Ok(RwLockReadGuard(PhantomData, self.1.read())) 101 } 102 write(&self) -> LockResult<RwLockWriteGuard<'_, T>>103 pub(crate) fn write(&self) -> LockResult<RwLockWriteGuard<'_, T>> { 104 Ok(RwLockWriteGuard(PhantomData, self.1.write())) 105 } 106 } 107 108 impl<'a, T: ?Sized> Deref for RwLockReadGuard<'a, T> { 109 type Target = T; deref(&self) -> &T110 fn deref(&self) -> &T { 111 self.1.deref() 112 } 113 } 114 115 impl<'a, T: ?Sized> Deref for RwLockWriteGuard<'a, T> { 116 type Target = T; deref(&self) -> &T117 fn deref(&self) -> &T { 118 self.1.deref() 119 } 120 } 121 122 impl<'a, T: ?Sized> DerefMut for RwLockWriteGuard<'a, T> { deref_mut(&mut self) -> &mut T123 fn deref_mut(&mut self) -> &mut T { 124 self.1.deref_mut() 125 } 126 } 127 128 impl Condvar { 129 #[inline] new() -> Condvar130 pub(crate) fn new() -> Condvar { 131 Condvar(PhantomData, parking_lot::Condvar::new()) 132 } 133 134 #[inline] notify_one(&self)135 pub(crate) fn notify_one(&self) { 136 self.1.notify_one(); 137 } 138 139 #[inline] notify_all(&self)140 pub(crate) fn notify_all(&self) { 141 self.1.notify_all(); 142 } 143 144 #[inline] wait<'a, T>( &self, mut guard: MutexGuard<'a, T>, ) -> LockResult<MutexGuard<'a, T>>145 pub(crate) fn wait<'a, T>( 146 &self, 147 mut guard: MutexGuard<'a, T>, 148 ) -> LockResult<MutexGuard<'a, T>> { 149 self.1.wait(&mut guard.1); 150 Ok(guard) 151 } 152 153 #[inline] wait_timeout<'a, T>( &self, mut guard: MutexGuard<'a, T>, timeout: Duration, ) -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)>154 pub(crate) fn wait_timeout<'a, T>( 155 &self, 156 mut guard: MutexGuard<'a, T>, 157 timeout: Duration, 158 ) -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> { 159 let wtr = self.1.wait_for(&mut guard.1, timeout); 160 Ok((guard, wtr)) 161 } 162 163 // Note: Additional methods `wait_timeout_ms`, `wait_timeout_until`, 164 // `wait_until` can be provided here as needed. 165 } 166 167 impl<'a, T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'a, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result168 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 169 fmt::Display::fmt(&self.1, f) 170 } 171 } 172 173 impl<'a, T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'a, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result174 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 175 fmt::Display::fmt(&self.1, f) 176 } 177 } 178 179 impl<'a, T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'a, T> { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result180 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 181 fmt::Display::fmt(&self.1, f) 182 } 183 } 184