diff --git a/wgpu-core/src/lock/ranked.rs b/wgpu-core/src/lock/ranked.rs index ecf37c1d77..4b5871d26f 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;