summaryrefslogtreecommitdiffstats
path: root/library/std/src/sys_common/mutex.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /library/std/src/sys_common/mutex.rs
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/std/src/sys_common/mutex.rs')
-rw-r--r--library/std/src/sys_common/mutex.rs93
1 files changed, 93 insertions, 0 deletions
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<imp::Mutex>` 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()
+ }
+}