pub struct Mutex<T, Lock = DefaultMutex> { /* private fields */ }Expand description
A blocking mutual exclusion lock for protecting shared data.
Each mutex has a type parameter which represents
the data that it is protecting. The data can only be accessed through the
RAII guards returned from lock and try_lock, or within the closures
passed to with_lock and try_with_lock, which guarantees that
the data is only ever accessed when the mutex is locked.
§Fairness
This is not a fair mutex.
§Overriding mutex implementations
This type is generic over a Lock type parameter which represents a raw
mutex implementation. By default, this is the DefaultMutex. To construct
a new Mutex with an alternative raw mutex implementation, use the
Mutex::new_with_raw_mutex cosntructor. See the module-level documentation
on overriding mutex
implementations for
more details.
When Lock implements the RawMutex trait, the Mutex type provides
the lock and try_lock methods, which return a RAII MutexGuard,
similar to the std::sync::Mutex API, in addition to the scoped
with_lock and try_with_lock methods. When Lock only implements
ScopedRawMutex, the Mutex type provides only the scoped
with_lock and try_with_lock methods.
:warning: Note that DefaultMutex does not implement RawMutex, so
using the lock and try_lock RAII API requires selecting an
alternative RawMutex implementation.
§Loom-specific behavior
When cfg(loom) is enabled, this mutex will use Loom’s simulated atomics,
checked UnsafeCell, and simulated spin loop hints.
Implementations§
Source§impl<T> Mutex<T>
impl<T> Mutex<T>
Sourcepub const fn new(data: T) -> Self
pub const fn new(data: T) -> Self
Returns a new Mutex protecting the provided data.
The returned Mutex is in an unlocked state, ready for use.
This constructor returns a mutex that uses the DefaultMutex
implementation. To use an alternative RawMutex type, use the
new_with_raw_mutex constructor, instead.
§Examples
use maitake_sync::blocking::Mutex;
let mutex = Mutex::new(0);Source§impl<T, Lock> Mutex<T, Lock>
impl<T, Lock> Mutex<T, Lock>
Sourcepub const fn new_with_raw_mutex(data: T, lock: Lock) -> Self
pub const fn new_with_raw_mutex(data: T, lock: Lock) -> Self
Returns a new Mutex protecting the provided data, using
lock type parameter as the raw mutex implementation.
See the module-level documentation on overriding mutex implementations for more details.
The returned Mutex is in an unlocked state, ready for use.
Sourcepub fn into_inner(self) -> T
pub fn into_inner(self) -> T
Consumes this Mutex, returning the guarded data.
Sourcepub fn get_mut(&mut self) -> &mut T
pub fn get_mut(&mut self) -> &mut 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
let mut lock = maitake_sync::blocking::Mutex::new(0);
lock.with_lock(|data| *data = 10);
assert_eq!(*lock.get_mut(), 10);Source§impl<T, Lock: ScopedRawMutex> Mutex<T, Lock>
impl<T, Lock: ScopedRawMutex> Mutex<T, Lock>
Sourcepub fn with_lock<U>(&self, f: impl FnOnce(&mut T) -> U) -> U
pub fn with_lock<U>(&self, f: impl FnOnce(&mut T) -> U) -> U
Lock this Mutex, blocking if it is not currently unlocked, and call
f() with the locked data once the lock is acquired.
When the Mutex is unlocked, this method locks it, calls f() with the
data protected by the Mutex, and then unlocks the Mutex and returns
the result of f(). If the Mutex is locked, this method blocks until
it is unlocked, and then takes the lock.
To return immediately rather than blocking, use Mutex::try_with_lock
instead.
This method is available as long as the Mutex’s Lock type parameter
implements the ScopedRawMutex trait. See the module-level
documentation on overriding mutex
implementations for
more details.
Sourcepub fn try_with_lock<U>(&self, f: impl FnOnce(&mut T) -> U) -> Option<U>
pub fn try_with_lock<U>(&self, f: impl FnOnce(&mut T) -> U) -> Option<U>
Attempt to lock this Mutex without blocking and call f() with the
locked data if the lock is acquired.
If the Mutex is unlocked, this method locks it, calls f() with the
data protected by the Mutex, and then unlocks the Mutex and returns
Some(U). Otherwise, if the lock is already held, this method
returns None immediately, without blocking.
To block until the Mutex is unlocked instead of returning None, use
Mutex::with_lock instead.
This method is available as long as the Mutex’s Lock type parameter
implements the ScopedRawMutex trait. See the module-level
documentation on overriding mutex
implementations for
more details.
§Returns
Source§impl<T, Lock> Mutex<T, Lock>where
Lock: RawMutex,
impl<T, Lock> Mutex<T, Lock>where
Lock: RawMutex,
Sourcepub fn try_lock(&self) -> Option<MutexGuard<'_, T, Lock>>
pub fn try_lock(&self) -> Option<MutexGuard<'_, T, Lock>>
Attempts to acquire this lock without blocking
If the lock could not be acquired at this time, then None is returned.
Otherwise, an RAII guard is returned. The lock will be unlocked when the
guard is dropped.
This function will never block.
This method is only availble if the Mutex’s Lock type parameter
implements the RawMutex trait. See the module-level documentation
on overriding mutex
implementations for
more details.
Sourcepub fn lock(&self) -> MutexGuard<'_, T, Lock>
pub fn lock(&self) -> MutexGuard<'_, T, Lock>
Acquires a mutex, blocking until it is locked.
This function will block until the mutex is available to lock. Upon returning, the thread is the only thread with the lock held. An RAII guard is returned to allow scoped unlock of the lock. When the guard goes out of scope, the mutex will be unlocked.
This method is only availble if the Mutex’s Lock type parameter
implements the RawMutex trait. See the module-level documentation
on overriding mutex
implementations for
more details.
Sourcepub unsafe fn force_unlock(&self)
pub unsafe fn force_unlock(&self)
Forcibly unlock the mutex.
If a lock is currently held, it will be released, regardless of who’s holding it. Of course, this is outrageously, disgustingly unsafe and you should never do it.
This method is only availble if the Mutex’s Lock type parameter
implements the RawMutex trait. See the module-level documentation
on overriding mutex
implementations for
more details.
§Safety
This deliberately violates mutual exclusion.
Only call this method when it is guaranteed that no stack frame that has previously locked the mutex will ever continue executing. Essentially, this is only okay to call when the kernel is oopsing and all code running on other cores has already been killed.
Trait Implementations§
impl<T: Send, Lock: Send> Send for Mutex<T, Lock>
impl<T: Send, Lock: Sync> Sync for Mutex<T, Lock>
T must be Send because shared references to the Mutex allow mutable
access to T (via a MutexGuard or Mutex::with_lock), which can be
used to move T between threads using core::mem::replace or similar.
T does not need to be Sync, and, in fact, a Mutex is often used
to protect !Sync data.
The Lock type must be Sync because sharing references to a mutex
implicitly share references to the Lock type as well — locking the mutex
references it.