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.
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; } }
-
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 aMutex
that proves you have read/write access at that point in time.MutexGuard
also holds onto a reference to theMutex
that generated it, withDeref
andDerefMut
implementations that give access to the data ofMutex
while the underlyingMutex
keeps that data private from the user. -
If
mutex.lock()
does not return aMutexGuard
, 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.