Skip to content

Commit a9961d4

Browse files
committed
Add new const_new function to lock_api
This new constructor allows creating mutexes, reentrant mutexes and RwLocks in a constant context on stable Rust by manually passing in the underlying raw mutex / rwlock.
1 parent fa294cd commit a9961d4

File tree

3 files changed

+51
-4
lines changed

3 files changed

+51
-4
lines changed

lock_api/src/mutex.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ pub unsafe trait RawMutexTimed: RawMutex {
9595
/// it is protecting. The data can only be accessed through the RAII guards
9696
/// returned from `lock` and `try_lock`, which guarantees that the data is only
9797
/// ever accessed when the mutex is locked.
98-
pub struct Mutex<R: RawMutex, T: ?Sized> {
98+
pub struct Mutex<R, T: ?Sized> {
9999
raw: R,
100100
data: UnsafeCell<T>,
101101
}
@@ -131,6 +131,18 @@ impl<R: RawMutex, T> Mutex<R, T> {
131131
}
132132
}
133133

134+
impl<R, T> Mutex<R, T> {
135+
/// Creates a new mutex based on a pre-existing raw mutex. This allows
136+
/// creating a mutex in a constant context on stable Rust.
137+
#[inline]
138+
pub const fn const_new(raw_mutex: R, val: T) -> Mutex<R, T> {
139+
Mutex {
140+
raw: raw_mutex,
141+
data: UnsafeCell::new(val),
142+
}
143+
}
144+
}
145+
134146
impl<R: RawMutex, T: ?Sized> Mutex<R, T> {
135147
/// # Safety
136148
///

lock_api/src/remutex.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub unsafe trait GetThreadId {
4747
fn nonzero_thread_id(&self) -> NonZeroUsize;
4848
}
4949

50-
struct RawReentrantMutex<R: RawMutex, G: GetThreadId> {
50+
struct RawReentrantMutex<R, G> {
5151
owner: AtomicUsize,
5252
lock_count: Cell<usize>,
5353
mutex: R,
@@ -145,7 +145,7 @@ impl<R: RawMutexTimed, G: GetThreadId> RawReentrantMutex<R, G> {
145145
///
146146
/// See [`Mutex`](struct.Mutex.html) for more details about the underlying mutex
147147
/// primitive.
148-
pub struct ReentrantMutex<R: RawMutex, G: GetThreadId, T: ?Sized> {
148+
pub struct ReentrantMutex<R, G, T: ?Sized> {
149149
raw: RawReentrantMutex<R, G>,
150150
data: UnsafeCell<T>,
151151
}
@@ -197,6 +197,28 @@ impl<R: RawMutex, G: GetThreadId, T> ReentrantMutex<R, G, T> {
197197
}
198198
}
199199

200+
impl<R, G, T> ReentrantMutex<R, G, T> {
201+
/// Creates a new reentrant mutex based on a pre-existing raw reentrant
202+
/// mutex and a helper to get the thread ID. This allows creating a
203+
/// reentrant mutex in a constant context on stable Rust.
204+
#[inline]
205+
pub const fn const_new(
206+
raw_reentrant_mutex: R,
207+
get_thread_id: G,
208+
val: T,
209+
) -> ReentrantMutex<R, G, T> {
210+
ReentrantMutex {
211+
data: UnsafeCell::new(val),
212+
raw: RawReentrantMutex {
213+
owner: AtomicUsize::new(0),
214+
lock_count: Cell::new(0),
215+
mutex: raw_reentrant_mutex,
216+
get_thread_id,
217+
},
218+
}
219+
}
220+
}
221+
200222
impl<R: RawMutex, G: GetThreadId, T: ?Sized> ReentrantMutex<R, G, T> {
201223
/// # Safety
202224
///

lock_api/src/rwlock.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ pub unsafe trait RawRwLockUpgradeTimed: RawRwLockUpgrade + RawRwLockTimed {
231231
/// allow concurrent access through readers. The RAII guards returned from the
232232
/// locking methods implement `Deref` (and `DerefMut` for the `write` methods)
233233
/// to allow access to the contained of the lock.
234-
pub struct RwLock<R: RawRwLock, T: ?Sized> {
234+
pub struct RwLock<R, T: ?Sized> {
235235
raw: R,
236236
data: UnsafeCell<T>,
237237
}
@@ -297,6 +297,19 @@ impl<R: RawRwLock, T> RwLock<R, T> {
297297
}
298298
}
299299

300+
impl<R, T> RwLock<R, T> {
301+
/// Creates a new new instance of an `RwLock<T>` based on a pre-existing
302+
/// `RawRwLock<T>`. This allows creating a `RwLock<T>` in a constant context
303+
/// on stable Rust.
304+
#[inline]
305+
pub const fn const_new(raw_rwlock: R, val: T) -> RwLock<R, T> {
306+
RwLock {
307+
data: UnsafeCell::new(val),
308+
raw: raw_rwlock,
309+
}
310+
}
311+
}
312+
300313
impl<R: RawRwLock, T: ?Sized> RwLock<R, T> {
301314
/// # Safety
302315
///

0 commit comments

Comments
 (0)