Crates.io | lock_order |
lib.rs | lock_order |
version | 0.1.0 |
source | src |
created_at | 2021-05-23 05:03:37.104755 |
updated_at | 2021-05-23 05:03:37.104755 |
description | Utility macro for helping produce a deterministic lock ordering to prevent deadlocks |
homepage | |
repository | https://github.com/alaric/lock_order |
max_upload_size | |
id | 401003 |
size | 9,153 |
This crate provides a simple lock ordering procmacro for ensuring a deterministic locking order, which is useful as a pattern to prevent deadlocks between fine-grain mutex use.
It also serves to remove the unwrap()
of panic-propagation between threads in the case of
poisoned locks. This is my favoured approach for handling an already panicking program, but
makes it difficult to find other non-valid usages of unwrap()
in the code.
mut
is optional based on if you want mutability, but must be prior to the identifierself.locks.connections
and will result in a
bound variable connections
as the last part of the full identifier.,
, they will be ordered
lexicographially by the bound variable name.Thus an example like this:
use lock_order::lock;
use std::sync::Mutex;
let lock1 = Mutex::new(1);
let lock2 = Mutex::new(2);
let lock3 = Mutex::new(3);
{
lock!(mut lock2, lock3, mut lock1);
*lock1 = 3 + *lock3;
*lock2 = 4 + *lock3;
}
Would expand to:
use lock_order::lock;
use std::sync::Mutex;
let lock1 = Mutex::new(1);
let lock2 = Mutex::new(2);
let lock3 = Mutex::new(3);
{
let (mut lock1, mut lock2, lock3) = (lock1.lock().unwrap(), lock2.lock().unwrap(),
lock3.lock().unwrap());
*lock1 = 3 + *lock3;
*lock2 = 4 + *lock3;
}
parking_lot
, which don't require unwrap()
.