From 651214ef74e35a1a320dc1883dd90ea26581b21a Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Wed, 1 May 2024 17:35:26 -0700 Subject: [PATCH] [core] Refactor `lock::ranked` to use `LockStateGuard`. Rather than implementing `Drop` for all three lock guard types to restore the lock analysis' per-thread state, let lock guards own values of a new type, `LockStateGuard`, with the appropriate `Drop` implementation. This is cleaner and shorter, and helps us implement `RwLock::downgrade` in a later commit. --- wgpu-core/src/lock/ranked.rs | 50 +++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/wgpu-core/src/lock/ranked.rs b/wgpu-core/src/lock/ranked.rs index ecf37c1d7..4b5871d26 100644 --- a/wgpu-core/src/lock/ranked.rs +++ b/wgpu-core/src/lock/ranked.rs @@ -81,7 +81,7 @@ pub struct Mutex { /// [mod]: crate::lock::ranked pub struct MutexGuard<'a, T> { inner: parking_lot::MutexGuard<'a, T>, - saved: LockState, + saved: LockStateGuard, } thread_local! { @@ -107,6 +107,26 @@ impl LockState { }; } +/// A container that restores a [`LockState`] when dropped. +/// +/// This type serves two purposes: +/// +/// - Operations like `RwLockWriteGuard::downgrade` would like to be able to +/// destructure lock guards and reassemble their pieces into new guards, but +/// if the guard type itself implements `Drop`, we can't destructure it +/// without unsafe code or pointless `Option`s whose state is almost always +/// statically known. +/// +/// - We can just implement `Drop` for this type once, and then use it in lock +/// guards, rather than implementing `Drop` separately for each guard type. +struct LockStateGuard(LockState); + +impl Drop for LockStateGuard { + fn drop(&mut self) { + release(self.0) + } +} + /// Check and record the acquisition of a lock with `new_rank`. /// /// Check that acquiring a lock with `new_rank` is permitted at this point, and @@ -170,17 +190,11 @@ impl Mutex { let saved = acquire(self.rank, Location::caller()); MutexGuard { inner: self.inner.lock(), - saved, + saved: LockStateGuard(saved), } } } -impl<'a, T> Drop for MutexGuard<'a, T> { - fn drop(&mut self) { - release(self.saved); - } -} - impl<'a, T> std::ops::Deref for MutexGuard<'a, T> { type Target = T; @@ -224,7 +238,7 @@ pub struct RwLock { /// [mod]: crate::lock::ranked pub struct RwLockReadGuard<'a, T> { inner: parking_lot::RwLockReadGuard<'a, T>, - saved: LockState, + saved: LockStateGuard, } /// A write guard produced by locking [`RwLock`] for writing. @@ -237,7 +251,7 @@ pub struct RwLockReadGuard<'a, T> { /// [mod]: crate::lock::ranked pub struct RwLockWriteGuard<'a, T> { inner: parking_lot::RwLockWriteGuard<'a, T>, - saved: LockState, + saved: LockStateGuard, } impl RwLock { @@ -253,7 +267,7 @@ impl RwLock { let saved = acquire(self.rank, Location::caller()); RwLockReadGuard { inner: self.inner.read(), - saved, + saved: LockStateGuard(saved), } } @@ -262,7 +276,7 @@ impl RwLock { let saved = acquire(self.rank, Location::caller()); RwLockWriteGuard { inner: self.inner.write(), - saved, + saved: LockStateGuard(saved), } } } @@ -273,18 +287,6 @@ impl std::fmt::Debug for RwLock { } } -impl<'a, T> Drop for RwLockReadGuard<'a, T> { - fn drop(&mut self) { - release(self.saved); - } -} - -impl<'a, T> Drop for RwLockWriteGuard<'a, T> { - fn drop(&mut self) { - release(self.saved); - } -} - impl<'a, T> std::ops::Deref for RwLockReadGuard<'a, T> { type Target = T;