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