with_lock

Prevent deadlocks

Docs

Example

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 log5` 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::::new(Mutex::new(2)); let b = WithLock::::new(Mutex::new(3)); let alock = a.withlock(|s| *s); let block = b.withlock(|s| *s); println!("{:?}", alock + block); let alock2 = a.withlock(|s| *s); let block2 = b.withlock(|s| *s); println!("{:?}", alock2 + block2); } ```

That code would log 5 twice. This is an example of how it can prevent deadlocks.

No code changes

For the people that want little to no code changes, with_lock exposes a custom Mutex 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 Mutex type that wouldn't deadlock would look like:

```rust use with_lock::Mutex;

fn main() { let a = Mutex::new(2); let b = Mutex::new(3); let alocked = a.lock(); let blocked = b.lock(); println!("{:?}", alocked + blocked); let alock2 = a.lock(); let block2 = b.lock(); println!("{:?}", alock2 + block2); } ```