wgpu_core/lock/
vanilla.rs

1//! Plain, uninstrumented wrappers around [`parking_lot`] lock types.
2//!
3//! These definitions are used when no particular lock instrumentation
4//! Cargo feature is selected.
5
6use core::{fmt, ops};
7
8use crate::lock::rank::LockRank;
9
10pub struct RankData;
11
12/// A plain wrapper around [`parking_lot::Mutex`].
13///
14/// This is just like [`parking_lot::Mutex`], except that our [`new`]
15/// method takes a rank, indicating where the new mutex should sit in
16/// `wgpu-core`'s lock ordering. The rank is ignored.
17///
18/// See the [`lock`] module documentation for other wrappers.
19///
20/// [`new`]: Mutex::new
21/// [`lock`]: crate::lock
22pub struct Mutex<T>(parking_lot::Mutex<T>);
23
24/// A guard produced by locking [`Mutex`].
25///
26/// This is just a wrapper around a [`parking_lot::MutexGuard`].
27pub struct MutexGuard<'a, T>(parking_lot::MutexGuard<'a, T>);
28
29impl<T> Mutex<T> {
30    pub fn new(_rank: LockRank, value: T) -> Mutex<T> {
31        Mutex(parking_lot::Mutex::new(value))
32    }
33
34    pub fn lock(&self) -> MutexGuard<'_, T> {
35        MutexGuard(self.0.lock())
36    }
37
38    pub fn get_mut(&mut self) -> &mut T {
39        self.0.get_mut()
40    }
41
42    pub fn into_inner(self) -> T {
43        self.0.into_inner()
44    }
45}
46
47impl<'a, T> ops::Deref for MutexGuard<'a, T> {
48    type Target = T;
49
50    fn deref(&self) -> &Self::Target {
51        self.0.deref()
52    }
53}
54
55impl<'a, T> ops::DerefMut for MutexGuard<'a, T> {
56    fn deref_mut(&mut self) -> &mut Self::Target {
57        self.0.deref_mut()
58    }
59}
60
61impl<T: fmt::Debug> fmt::Debug for Mutex<T> {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        self.0.fmt(f)
64    }
65}
66
67/// A plain wrapper around [`parking_lot::RwLock`].
68///
69/// This is just like [`parking_lot::RwLock`], except that our [`new`]
70/// method takes a rank, indicating where the new mutex should sit in
71/// `wgpu-core`'s lock ordering. The rank is ignored.
72///
73/// See the [`lock`] module documentation for other wrappers.
74///
75/// [`new`]: RwLock::new
76/// [`lock`]: crate::lock
77pub struct RwLock<T>(parking_lot::RwLock<T>);
78
79/// A read guard produced by locking [`RwLock`] as a reader.
80///
81/// This is just a wrapper around a [`parking_lot::RwLockReadGuard`].
82pub struct RwLockReadGuard<'a, T>(parking_lot::RwLockReadGuard<'a, T>);
83
84/// A write guard produced by locking [`RwLock`] as a writer.
85///
86/// This is just a wrapper around a [`parking_lot::RwLockWriteGuard`].
87pub struct RwLockWriteGuard<'a, T>(parking_lot::RwLockWriteGuard<'a, T>);
88
89impl<T> RwLock<T> {
90    pub fn new(_rank: LockRank, value: T) -> RwLock<T> {
91        RwLock(parking_lot::RwLock::new(value))
92    }
93
94    pub fn read(&self) -> RwLockReadGuard<'_, T> {
95        RwLockReadGuard(self.0.read())
96    }
97
98    pub fn write(&self) -> RwLockWriteGuard<'_, T> {
99        RwLockWriteGuard(self.0.write())
100    }
101
102    /// Force an read-unlock operation on this lock.
103    ///
104    /// Safety:
105    /// - A read lock must be held which is not held by a guard.
106    pub unsafe fn force_unlock_read(&self, _data: RankData) {
107        unsafe { self.0.force_unlock_read() };
108    }
109}
110
111impl<'a, T> RwLockReadGuard<'a, T> {
112    // Forget the read guard, leaving the lock in a locked state with no guard.
113    //
114    // Equivalent to std::mem::forget, but preserves the information about the lock
115    // rank.
116    pub fn forget(this: Self) -> RankData {
117        core::mem::forget(this.0);
118
119        RankData
120    }
121}
122
123impl<T: fmt::Debug> fmt::Debug for RwLock<T> {
124    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125        self.0.fmt(f)
126    }
127}
128
129impl<'a, T> ops::Deref for RwLockReadGuard<'a, T> {
130    type Target = T;
131
132    fn deref(&self) -> &Self::Target {
133        self.0.deref()
134    }
135}
136
137impl<'a, T> ops::Deref for RwLockWriteGuard<'a, T> {
138    type Target = T;
139
140    fn deref(&self) -> &Self::Target {
141        self.0.deref()
142    }
143}
144
145impl<'a, T> ops::DerefMut for RwLockWriteGuard<'a, T> {
146    fn deref_mut(&mut self) -> &mut Self::Target {
147        self.0.deref_mut()
148    }
149}