pub struct Mutex<T> { /* private fields */ }
Expand description

A mutex based on critical sections.

Design

std::sync::Mutex has two purposes. It converts types that are Send but not Sync into types that are both; and it provides interior mutability. critical_section::Mutex, on the other hand, only adds Sync. It does not provide interior mutability.

This was a conscious design choice. It is possible to create multiple CriticalSection tokens, either by nesting critical sections or Copying an existing token. As a result, it would not be sound for Mutex::borrow to return &mut T, because there would be nothing to prevent calling borrow multiple times to create aliased &mut T references.

The solution is to include a runtime check to ensure that each resource is borrowed only once. This is what std::sync::Mutex does. However, this is a runtime cost that may not be required in all circumstances. For instance, Mutex<Cell<T>> never needs to create &mut T or equivalent.

If &mut T is needed, the simplest solution is to use Mutex<RefCell<T>>, which is the closest analogy to std::sync::Mutex. RefCell inserts the exact runtime check necessary to guarantee that the &mut T reference is unique.

To reduce verbosity when using Mutex<RefCell<T>>, we reimplement some of RefCell’s methods on it directly.


static FOO: Mutex<RefCell<i32>> = Mutex::new(RefCell::new(42));

fn main() {
    let cs = unsafe { CriticalSection::new() };
    // Instead of calling this
    let _ = FOO.borrow(cs).take();
    // Call this
    let _ = FOO.take(cs);
    // `RefCell::borrow` and `RefCell::borrow_mut` are renamed to
    // `borrow_ref` and `borrow_ref_mut` to avoid name collisions
    let _: &mut i32 = &mut *FOO.borrow_ref_mut(cs);
}

Implementations

Creates a new mutex.

Gets a mutable reference to the contained value when the mutex is already uniquely borrowed.

This does not require locking or a critical section since it takes &mut self, which guarantees unique ownership already. Care must be taken when using this method to unsafely access static mut variables, appropriate fences must be used to prevent unwanted optimizations.

Unwraps the contained value, consuming the mutex.

Borrows the data for the duration of the critical section.

Borrow the data and call RefCell::replace

This is equivalent to self.borrow(cs).replace(t)

Panics

This call could panic. See the documentation for RefCell::replace for more details.

Borrow the data and call RefCell::replace_with

This is equivalent to self.borrow(cs).replace_with(f)

Panics

This call could panic. See the documentation for RefCell::replace_with for more details.

Borrow the data and call RefCell::borrow

This is equivalent to self.borrow(cs).borrow()

Panics

This call could panic. See the documentation for RefCell::borrow for more details.

Borrow the data and call RefCell::borrow_mut

This is equivalent to self.borrow(cs).borrow_mut()

Panics

This call could panic. See the documentation for RefCell::borrow_mut for more details.

Borrow the data and call RefCell::take

This is equivalent to self.borrow(cs).take()

Panics

This call could panic. See the documentation for RefCell::take for more details.

Trait Implementations

Formats the value using the given formatter. Read more

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

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.