diff options
| author | bors <bors@rust-lang.org> | 2022-06-18 15:18:50 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-06-18 15:18:50 +0000 |
| commit | ec21d7ea3ca8e96863f175fbd4a6bfee79529d6c (patch) | |
| tree | 5415778c4f2c10e5a646d04b71baf2560f1551db /library/std/src | |
| parent | 2cec6874c086a8fa107115dcca73d93228a3bef6 (diff) | |
| parent | 34895ded2c76cc87dc6ff33adaa541c239d416bf (diff) | |
| download | rust-ec21d7ea3ca8e96863f175fbd4a6bfee79529d6c.tar.gz rust-ec21d7ea3ca8e96863f175fbd4a6bfee79529d6c.zip | |
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.
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/sync/mutex.rs | 6 | ||||
| -rw-r--r-- | library/std/src/sync/poison.rs | 9 | ||||
| -rw-r--r-- | library/std/src/sync/rwlock.rs | 8 |
3 files changed, 15 insertions, 8 deletions
diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index b2fbb77204a..31342a89054 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -423,7 +423,7 @@ impl<T: ?Sized> Mutex<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 @@ impl<T: ?Sized> Mutex<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 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> { 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 }) } } diff --git a/library/std/src/sync/poison.rs b/library/std/src/sync/poison.rs index ba91fb0499f..9c918be3387 100644 --- a/library/std/src/sync/poison.rs +++ b/library/std/src/sync/poison.rs @@ -23,8 +23,15 @@ impl 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) } } diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index 4f1b4bedaab..9517e7e1f03 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -434,7 +434,7 @@ impl<T: ?Sized> RwLock<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 @@ impl<T: ?Sized> RwLock<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 @@ impl<T> From<T> for RwLock<T> { 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 }) } } |
