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
MutexGuardspecifically. -
MutexGuardis a value generated by aMutexthat proves you have read/write access at that point in time.MutexGuardalso holds onto a reference to theMutexthat generated it, withDerefandDerefMutimplementations that give access to the data ofMutexwhile the underlyingMutexkeeps 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
mutexvariable 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.