From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- library/std/src/sys_common/mutex.rs | 93 +++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 library/std/src/sys_common/mutex.rs (limited to 'library/std/src/sys_common/mutex.rs') diff --git a/library/std/src/sys_common/mutex.rs b/library/std/src/sys_common/mutex.rs new file mode 100644 index 000000000..48479f5bd --- /dev/null +++ b/library/std/src/sys_common/mutex.rs @@ -0,0 +1,93 @@ +use crate::sys::locks as imp; + +/// An OS-based mutual exclusion lock, meant for use in static variables. +/// +/// This mutex has a const constructor ([`StaticMutex::new`]), does not +/// implement `Drop` to cleanup resources, and causes UB when used reentrantly. +/// +/// This mutex does not implement poisoning. +/// +/// This is a wrapper around `imp::Mutex` that does *not* call `init()` and +/// `destroy()`. +pub struct StaticMutex(imp::Mutex); + +unsafe impl Sync for StaticMutex {} + +impl StaticMutex { + /// Creates a new mutex for use. + #[inline] + pub const fn new() -> Self { + Self(imp::Mutex::new()) + } + + /// Calls raw_lock() and then returns an RAII guard to guarantee the mutex + /// will be unlocked. + /// + /// It is undefined behaviour to call this function while locked by the + /// same thread. + #[inline] + pub unsafe fn lock(&'static self) -> StaticMutexGuard { + self.0.lock(); + StaticMutexGuard(&self.0) + } +} + +#[must_use] +pub struct StaticMutexGuard(&'static imp::Mutex); + +impl Drop for StaticMutexGuard { + #[inline] + fn drop(&mut self) { + unsafe { + self.0.unlock(); + } + } +} + +/// An OS-based mutual exclusion lock. +/// +/// This mutex cleans up its resources in its `Drop` implementation, may safely +/// be moved (when not borrowed), and does not cause UB when used reentrantly. +/// +/// This mutex does not implement poisoning. +/// +/// This is either a wrapper around `LazyBox` or `imp::Mutex`, +/// depending on the platform. It is boxed on platforms where `imp::Mutex` may +/// not be moved. +pub struct MovableMutex(imp::MovableMutex); + +unsafe impl Sync for MovableMutex {} + +impl MovableMutex { + /// Creates a new mutex. + #[inline] + pub const fn new() -> Self { + Self(imp::MovableMutex::new()) + } + + pub(super) fn raw(&self) -> &imp::Mutex { + &self.0 + } + + /// Locks the mutex blocking the current thread until it is available. + #[inline] + pub fn raw_lock(&self) { + unsafe { self.0.lock() } + } + + /// Attempts to lock the mutex without blocking, returning whether it was + /// successfully acquired or not. + #[inline] + pub fn try_lock(&self) -> bool { + unsafe { self.0.try_lock() } + } + + /// Unlocks the mutex. + /// + /// Behavior is undefined if the current thread does not actually hold the + /// mutex. + #[inline] + pub unsafe fn raw_unlock(&self) { + self.0.unlock() + } +} -- cgit v1.2.3