---
minutes: 10
---

# Token Types with Data: Mutex Guards

Sometimes, a token type needs additional data. A mutex guard is an example of a
token that represents permission + data.

```rust,editable
use std::sync::{Arc, Mutex, MutexGuard};

fn main() {
    let mutex = Arc::new(Mutex::new(42));
    let try_mutex_guard: Result<MutexGuard<'_, _>, _> = mutex.lock();
    if let Ok(mut guarded) = try_mutex_guard {
        // The acquired MutexGuard is proof of exclusive access.
        *guarded = 451;
    }
}
```

<details>

<!-- TODO: Reference the Mutex section of the RAII chapter once that is merged.
Remind the students that the RAII section specifically covered automatic mutex unlocking and did not talk about access to the data.
-->

- Mutexes enforce mutual exclusion of read/write access to a value. We've
  covered Mutexes earlier in this course already (See: RAII/Mutex), but here
  we're looking at `MutexGuard` specifically.

- `MutexGuard` is a value generated by a `Mutex` that proves you have read/write
  access at that point in time.

  `MutexGuard` also holds onto a reference to the `Mutex` that generated it,
  with `Deref` and `DerefMut` implementations that give access to the data of
  `Mutex` while the underlying `Mutex` keeps that data private from the user.

- If `mutex.lock()` does not return a `MutexGuard`, you don't have permission to
  change the value within the mutex.

  Not only do you have no permission, but you have no means to access the mutex
  data unless you gain a `MutexGuard`.

  This contrasts with C++, where mutexes and lock guards do not control access
  to the data itself, acting only as a flag that a user must remember to check
  every time they read or manipulate data.

- Demonstrate: make the `mutex` variable mutable then try to dereference it to
  change its value. Show how there's no deref implementation for it, and no
  other way to get to the data held by it other than getting a mutex guard.

</details>
