Skip to content

Commit ec21d7e

Browse files
committed
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.
2 parents 2cec687 + 34895de commit ec21d7e

File tree

3 files changed

+15
-8
lines changed

3 files changed

+15
-8
lines changed

library/std/src/sync/mutex.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ impl<T: ?Sized> Mutex<T> {
423423
T: Sized,
424424
{
425425
let data = self.data.into_inner();
426-
poison::map_result(self.poison.borrow(), |_| data)
426+
poison::map_result(self.poison.borrow(), |()| data)
427427
}
428428

429429
/// Returns a mutable reference to the underlying data.
@@ -448,7 +448,7 @@ impl<T: ?Sized> Mutex<T> {
448448
#[stable(feature = "mutex_get_mut", since = "1.6.0")]
449449
pub fn get_mut(&mut self) -> LockResult<&mut T> {
450450
let data = self.data.get_mut();
451-
poison::map_result(self.poison.borrow(), |_| data)
451+
poison::map_result(self.poison.borrow(), |()| data)
452452
}
453453
}
454454

@@ -497,7 +497,7 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
497497

498498
impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
499499
unsafe fn new(lock: &'mutex Mutex<T>) -> LockResult<MutexGuard<'mutex, T>> {
500-
poison::map_result(lock.poison.borrow(), |guard| MutexGuard { lock, poison: guard })
500+
poison::map_result(lock.poison.guard(), |guard| MutexGuard { lock, poison: guard })
501501
}
502502
}
503503

library/std/src/sync/poison.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,15 @@ impl Flag {
2323
Flag { failed: AtomicBool::new(false) }
2424
}
2525

26+
/// Check the flag for an unguarded borrow, where we only care about existing poison.
2627
#[inline]
27-
pub fn borrow(&self) -> LockResult<Guard> {
28+
pub fn borrow(&self) -> LockResult<()> {
29+
if self.get() { Err(PoisonError::new(())) } else { Ok(()) }
30+
}
31+
32+
/// Check the flag for a guarded borrow, where we may also set poison when `done`.
33+
#[inline]
34+
pub fn guard(&self) -> LockResult<Guard> {
2835
let ret = Guard { panicking: thread::panicking() };
2936
if self.get() { Err(PoisonError::new(ret)) } else { Ok(ret) }
3037
}

library/std/src/sync/rwlock.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ impl<T: ?Sized> RwLock<T> {
434434
T: Sized,
435435
{
436436
let data = self.data.into_inner();
437-
poison::map_result(self.poison.borrow(), |_| data)
437+
poison::map_result(self.poison.borrow(), |()| data)
438438
}
439439

440440
/// Returns a mutable reference to the underlying data.
@@ -461,7 +461,7 @@ impl<T: ?Sized> RwLock<T> {
461461
#[stable(feature = "rwlock_get_mut", since = "1.6.0")]
462462
pub fn get_mut(&mut self) -> LockResult<&mut T> {
463463
let data = self.data.get_mut();
464-
poison::map_result(self.poison.borrow(), |_| data)
464+
poison::map_result(self.poison.borrow(), |()| data)
465465
}
466466
}
467467

@@ -510,13 +510,13 @@ impl<T> From<T> for RwLock<T> {
510510

511511
impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
512512
unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> {
513-
poison::map_result(lock.poison.borrow(), |_| RwLockReadGuard { lock })
513+
poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard { lock })
514514
}
515515
}
516516

517517
impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
518518
unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockWriteGuard<'rwlock, T>> {
519-
poison::map_result(lock.poison.borrow(), |guard| RwLockWriteGuard { lock, poison: guard })
519+
poison::map_result(lock.poison.guard(), |guard| RwLockWriteGuard { lock, poison: guard })
520520
}
521521
}
522522

0 commit comments

Comments
 (0)