Deadlock freedom
Say you have this code:
```rust,no_run use std::sync::Mutex;
fn main() {
let a = Mutex::new(2);
let b = Mutex::new(3);
let alock = a.lock().unwrap();
let block = b.lock().unwrap();
println!("{:?}", *alock + *block);
let alock2 = a.lock().unwrap();
let block2 = b.lock().unwrap();
println!("{:?}", *alock2 + *block2);
}
``
That code will log
5` once, when it should log twice. As you can see here, it is deadlocking.
However, we can prevent this by replacing our manual calls of .lock
with .with_lock
. Code that wouldn't error would look something like:
```rust use std::sync::Mutex; use with_lock::WithLock;
fn main() {
let a = WithLock::
That code would log 5
twice. This is an example of how it can prevent deadlocks.
For the people that want little to no code changes, with_lock
exposes a custom MutexCell type.
Code that would produce deadlocks would look like this:
```rust,no_run use std::sync::Mutex;
fn main() { let a = Mutex::new(2); let b = Mutex::new(3); let alock = a.lock().unwrap(); let block = b.lock().unwrap(); println!("{:?}", *alock + *block); let alock2 = a.lock().unwrap(); let block2 = b.lock().unwrap(); println!("{:?}", *alock2 + *block2); } ```
And using the custom MutexCell type that wouldn't deadlock would look like:
```rust use with_lock::MutexCell;
fn main() { let a = MutexCell::new(2); let b = MutexCell::new(3); let alocked = a.get(); let blocked = b.get(); println!("{:?}", alocked + blocked); let alock2 = a.get(); let block2 = b.get(); println!("{:?}", alock2 + block2); } ```