#[repr(align(128))]
pub struct Mutex<T: ?Sized> { raw: RawMutex, value: UnsafeCell<T>, }
Expand description

A high-level primitive that provides safe, mutable access to a shared resource.

Unlike more traditional mutexes, Mutex can safely provide both shared, immutable access (via read_lock()) as well as exclusive, mutable access (via lock()) to an underlying resource with no loss of performance.

Poisoning

Mutex does not support lock poisoning so if a thread panics while holding the lock, the poisoned data will be accessible by other threads in your program. If you need to guarantee that other threads cannot access poisoned data then you may wish to wrap this Mutex inside another type that provides the poisoning feature. See the implementation of std::sync::Mutex for an example of this.

Fairness

This Mutex implementation does not guarantee that threads will acquire the lock in the same order that they call lock() or read_lock(). However it will attempt to prevent long-term starvation: if a thread repeatedly fails to acquire the lock beyond a threshold then all other threads will fail to acquire the lock until the starved thread has acquired it.

Similarly, this Mutex will attempt to balance reader and writer threads: once there is a writer thread waiting to acquire the lock no new reader threads will be allowed to acquire it. However, any reader threads that were already waiting will still be allowed to acquire it.

Examples

use std::sync::Arc;
use std::thread;
use std::sync::mpsc::channel;

use cros_async::{block_on, sync::Mutex};

const N: usize = 10;

// Spawn a few threads to increment a shared variable (non-atomically), and
// let the main thread know once all increments are done.
//
// Here we're using an Arc to share memory among threads, and the data inside
// the Arc is protected with a mutex.
let data = Arc::new(Mutex::new(0));

let (tx, rx) = channel();
for _ in 0..N {
    let (data, tx) = (Arc::clone(&data), tx.clone());
    thread::spawn(move || {
        // The shared state can only be accessed once the lock is held.
        // Our non-atomic increment is safe because we're the only thread
        // which can access the shared state when the lock is held.
        let mut data = block_on(data.lock());
        *data += 1;
        if *data == N {
            tx.send(()).unwrap();
        }
        // the lock is unlocked here when `data` goes out of scope.
    });
}

rx.recv().unwrap();

Fields

raw: RawMutexvalue: UnsafeCell<T>

Implementations

Create a new, unlocked Mutex ready for use.

Consume the Mutex and return the contained value. This method does not perform any locking as the compiler will guarantee that there are no other references to self and the caller owns the Mutex.

Acquires exclusive, mutable access to the resource protected by the Mutex, blocking the current thread until it is able to do so. Upon returning, the current thread will be the only thread with access to the resource. The Mutex will be released when the returned MutexGuard is dropped.

Calling lock() while holding a MutexGuard or a MutexReadGuard will cause a deadlock.

Callers that are not in an async context may wish to use the block_on method to block the thread until the Mutex is acquired.

Acquires shared, immutable access to the resource protected by the Mutex, blocking the current thread until it is able to do so. Upon returning there may be other threads that also have immutable access to the resource but there will not be any threads that have mutable access to the resource. When the returned MutexReadGuard is dropped the thread releases its access to the resource.

Calling read_lock() while holding a MutexReadGuard may deadlock. Calling read_lock() while holding a MutexGuard will deadlock.

Callers that are not in an async context may wish to use the block_on method to block the thread until the Mutex is acquired.

Trait Implementations

Returns the “default value” for a type. Read more
Converts to this type from the input type.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more
Converts to this type from the input type.

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.