diff options
Diffstat (limited to 'src/sync/mutex.rs')
-rw-r--r-- | src/sync/mutex.rs | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/src/sync/mutex.rs b/src/sync/mutex.rs index 642058b..21e44ca 100644 --- a/src/sync/mutex.rs +++ b/src/sync/mutex.rs @@ -1,3 +1,5 @@ +#![cfg_attr(not(feature = "sync"), allow(unreachable_pub, dead_code))] + use crate::sync::batch_semaphore as semaphore; use std::cell::UnsafeCell; @@ -115,7 +117,6 @@ use std::sync::Arc; /// [`std::sync::Mutex`]: struct@std::sync::Mutex /// [`Send`]: trait@std::marker::Send /// [`lock`]: method@Mutex::lock -#[derive(Debug)] pub struct Mutex<T: ?Sized> { s: semaphore::Semaphore, c: UnsafeCell<T>, @@ -220,6 +221,27 @@ impl<T: ?Sized> Mutex<T> { } } + /// Creates a new lock in an unlocked state ready for use. + /// + /// # Examples + /// + /// ``` + /// use tokio::sync::Mutex; + /// + /// static LOCK: Mutex<i32> = Mutex::const_new(5); + /// ``` + #[cfg(all(feature = "parking_lot", not(all(loom, test)),))] + #[cfg_attr(docsrs, doc(cfg(feature = "parking_lot")))] + pub const fn const_new(t: T) -> Self + where + T: Sized, + { + Self { + c: UnsafeCell::new(t), + s: semaphore::Semaphore::const_new(1), + } + } + /// Locks this mutex, causing the current task /// to yield until the lock has been acquired. /// When the lock has been acquired, function returns a [`MutexGuard`]. @@ -305,6 +327,30 @@ impl<T: ?Sized> Mutex<T> { } } + /// Returns a mutable reference to the underlying data. + /// + /// Since this call borrows the `Mutex` mutably, no actual locking needs to + /// take place -- the mutable borrow statically guarantees no locks exist. + /// + /// # Examples + /// + /// ``` + /// use tokio::sync::Mutex; + /// + /// fn main() { + /// let mut mutex = Mutex::new(1); + /// + /// let n = mutex.get_mut(); + /// *n = 2; + /// } + /// ``` + pub fn get_mut(&mut self) -> &mut T { + unsafe { + // Safety: This is https://github.com/rust-lang/rust/pull/76936 + &mut *self.c.get() + } + } + /// Attempts to acquire the lock, and returns [`TryLockError`] if the lock /// is currently held somewhere else. /// @@ -373,6 +419,20 @@ where } } +impl<T> std::fmt::Debug for Mutex<T> +where + T: std::fmt::Debug, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut d = f.debug_struct("Mutex"); + match self.try_lock() { + Ok(inner) => d.field("data", &*inner), + Err(_) => d.field("data", &format_args!("<locked>")), + }; + d.finish() + } +} + // === impl MutexGuard === impl<T: ?Sized> Drop for MutexGuard<'_, T> { |