1 //! Abstracts over sync primitive implementations. 2 //! 3 //! Optionally, we allow the Rust standard library's `RwLock` to be replaced 4 //! with the `parking_lot` crate's implementation. This may provide improved 5 //! performance in some cases. However, the `parking_lot` dependency is an 6 //! opt-in feature flag. Because `parking_lot::RwLock` has a slightly different 7 //! API than `std::sync::RwLock` (it does not support poisoning on panics), we 8 //! wrap it with a type that provides the same method signatures. This allows us 9 //! to transparently swap `parking_lot` in without changing code at the callsite. 10 #[allow(unused_imports)] // may be used later; 11 pub(crate) use std::sync::{LockResult, PoisonError, TryLockResult}; 12 13 #[cfg(not(feature = "parking_lot"))] 14 pub(crate) use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}; 15 16 #[cfg(feature = "parking_lot")] 17 pub(crate) use self::parking_lot_impl::*; 18 19 #[cfg(feature = "parking_lot")] 20 mod parking_lot_impl { 21 pub(crate) use parking_lot::{RwLockReadGuard, RwLockWriteGuard}; 22 use std::sync::{LockResult, TryLockError, TryLockResult}; 23 24 #[derive(Debug)] 25 pub(crate) struct RwLock<T> { 26 inner: parking_lot::RwLock<T>, 27 } 28 29 impl<T> RwLock<T> { new(val: T) -> Self30 pub(crate) fn new(val: T) -> Self { 31 Self { 32 inner: parking_lot::RwLock::new(val), 33 } 34 } 35 36 #[inline] get_mut(&mut self) -> LockResult<&mut T>37 pub(crate) fn get_mut(&mut self) -> LockResult<&mut T> { 38 Ok(self.inner.get_mut()) 39 } 40 41 #[inline] read(&self) -> LockResult<RwLockReadGuard<'_, T>>42 pub(crate) fn read(&self) -> LockResult<RwLockReadGuard<'_, T>> { 43 Ok(self.inner.read()) 44 } 45 46 #[inline] 47 #[allow(dead_code)] // may be used later; try_read(&self) -> TryLockResult<RwLockReadGuard<'_, T>>48 pub(crate) fn try_read(&self) -> TryLockResult<RwLockReadGuard<'_, T>> { 49 self.inner.try_read().ok_or(TryLockError::WouldBlock) 50 } 51 52 #[inline] write(&self) -> LockResult<RwLockWriteGuard<'_, T>>53 pub(crate) fn write(&self) -> LockResult<RwLockWriteGuard<'_, T>> { 54 Ok(self.inner.write()) 55 } 56 } 57 } 58