Auto merge of #97924 - cuviper:unguarded-poison, r=Mark-Simulacrum
Avoid `thread::panicking()` in non-poisoning methods of `Mutex` and `RwLock` `Mutex::lock()` and `RwLock::write()` are poison-guarded against panics, in that they set the poison flag if a panic occurs while they're locked. But if we're already in a panic (`thread::panicking()`), they leave the poison flag alone. That check is a bit of a waste for methods that never set the poison flag though, namely `get_mut()`, `into_inner()`, and `RwLock::read()`. These use-cases are now split to avoid that unnecessary call.
This commit is contained in:
commit
ec21d7ea3c
@ -423,7 +423,7 @@ pub fn into_inner(self) -> LockResult<T>
|
||||
T: Sized,
|
||||
{
|
||||
let data = self.data.into_inner();
|
||||
poison::map_result(self.poison.borrow(), |_| data)
|
||||
poison::map_result(self.poison.borrow(), |()| data)
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the underlying data.
|
||||
@ -448,7 +448,7 @@ pub fn into_inner(self) -> LockResult<T>
|
||||
#[stable(feature = "mutex_get_mut", since = "1.6.0")]
|
||||
pub fn get_mut(&mut self) -> LockResult<&mut T> {
|
||||
let data = self.data.get_mut();
|
||||
poison::map_result(self.poison.borrow(), |_| data)
|
||||
poison::map_result(self.poison.borrow(), |()| data)
|
||||
}
|
||||
}
|
||||
|
||||
@ -497,7 +497,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
||||
impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
|
||||
unsafe fn new(lock: &'mutex Mutex<T>) -> LockResult<MutexGuard<'mutex, T>> {
|
||||
poison::map_result(lock.poison.borrow(), |guard| MutexGuard { lock, poison: guard })
|
||||
poison::map_result(lock.poison.guard(), |guard| MutexGuard { lock, poison: guard })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,15 @@ pub const fn new() -> Flag {
|
||||
Flag { failed: AtomicBool::new(false) }
|
||||
}
|
||||
|
||||
/// Check the flag for an unguarded borrow, where we only care about existing poison.
|
||||
#[inline]
|
||||
pub fn borrow(&self) -> LockResult<Guard> {
|
||||
pub fn borrow(&self) -> LockResult<()> {
|
||||
if self.get() { Err(PoisonError::new(())) } else { Ok(()) }
|
||||
}
|
||||
|
||||
/// Check the flag for a guarded borrow, where we may also set poison when `done`.
|
||||
#[inline]
|
||||
pub fn guard(&self) -> LockResult<Guard> {
|
||||
let ret = Guard { panicking: thread::panicking() };
|
||||
if self.get() { Err(PoisonError::new(ret)) } else { Ok(ret) }
|
||||
}
|
||||
|
@ -434,7 +434,7 @@ pub fn into_inner(self) -> LockResult<T>
|
||||
T: Sized,
|
||||
{
|
||||
let data = self.data.into_inner();
|
||||
poison::map_result(self.poison.borrow(), |_| data)
|
||||
poison::map_result(self.poison.borrow(), |()| data)
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the underlying data.
|
||||
@ -461,7 +461,7 @@ pub fn into_inner(self) -> LockResult<T>
|
||||
#[stable(feature = "rwlock_get_mut", since = "1.6.0")]
|
||||
pub fn get_mut(&mut self) -> LockResult<&mut T> {
|
||||
let data = self.data.get_mut();
|
||||
poison::map_result(self.poison.borrow(), |_| data)
|
||||
poison::map_result(self.poison.borrow(), |()| data)
|
||||
}
|
||||
}
|
||||
|
||||
@ -510,13 +510,13 @@ fn from(t: T) -> Self {
|
||||
|
||||
impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
|
||||
unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> {
|
||||
poison::map_result(lock.poison.borrow(), |_| RwLockReadGuard { lock })
|
||||
poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard { lock })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
|
||||
unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockWriteGuard<'rwlock, T>> {
|
||||
poison::map_result(lock.poison.borrow(), |guard| RwLockWriteGuard { lock, poison: guard })
|
||||
poison::map_result(lock.poison.guard(), |guard| RwLockWriteGuard { lock, poison: guard })
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user