Provides a Send
-able cell type whose contents can be accessed only via an
unforgeable token.
```rust let mut token = ArcToken::new();
let lock = TokenLock::new(token.id(), 1); assert_eq!(*lock.read(&token).unwrap(), 1);
let mut guard = lock.write(&mut token).unwrap(); assert_eq!(*guard, 1); *guard = 2; ```
TokenLock
implements Send
and Sync
so it can be shared between threads,
but only the thread holding the original Token
can access its contents.
Token
cannot be cloned:
```rust let lock = Arc::new(TokenLock::new(token.id(), 1));
let lock1 = Arc::clone(&lock); thread::Builder::new().spawn(move || { let lock1 = lock1; let mut token1 = token;
// I have `Token` so I can get a mutable reference to the contents
lock_1.write(&mut token_1).unwrap();
}).unwrap();
// can't access the contents; I no longer have Token
// lock.write(&mut token).unwrap();
```
The lifetime of the returned reference is limited by both of the TokenLock
and Token
.
```compile_fail
let mut token = ArcToken::new();
let lock = TokenLock::new(token.id(), 1);
let guard = lock.write(&mut token).unwrap();
drop(lock); // compile error: guard
cannot outlive TokenLock
drop(guard);
```
```compile_fail
drop(token); // compile error: guard
cannot outlive Token
drop(guard);
```
It also prevents from forming a reference to the contained value when there already is a mutable reference to it:
```compile_fail
let writeguard = lock.write(&mut token).unwrap(); let readguard = lock.read(&token).unwrap(); // compile error drop(write_guard); ```
While allowing multiple immutable references:
rust
let read_guard1 = lock.read(&token).unwrap();
let read_guard2 = lock.read(&token).unwrap();
License: MIT/Apache-2.0