- Notifications
You must be signed in to change notification settings - Fork6
A Mutex wrapper tracking acquisition order
License
Apache-2.0, MIT licenses found
Licenses found
bertptrs/tracing-mutex
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Avoid deadlocks in your mutexes by acquiring them in a consistent order, or else.
In any code that uses mutexes or locks, you quickly run into the possibility of deadlock. With justtwo mutexesFoo
andBar
you can already deadlock, assuming one thread first locksFoo
thenattempts to getBar
and another first getsBar
then tries to getFoo
. Now both threads arewaiting for each other to release the lock they already have.
One simple way to get around this is by ensuring that, when you need bothFoo
andBar
, youshould first acquireFoo
then you can never deadlock. Of course, with just two mutexes, this iseasy to keep track of, but once your code starts to grow you might lose track of all thesedependencies. That's where this crate comes in.
This crate tracks the order in which you acquire locks in your code, tries to build a dependencytree out of it, and panics if your dependencies would create a cycle. It provides replacements forexisting synchronization primitives with an identical API, and should be a drop-in replacement.
Inspired bythis blogpost, which references a similar behaviour implemented byAbseil for their mutexes.This article goes into more depth on the exactimplementation.
Add this dependency to yourCargo.lock
file like any other:
[dependencies]tracing-mutex ="0.3"
Then use the locks provided by this library instead of the ones you would use otherwise.Replacements for the synchronization primitives instd::sync
can be found in thestdsync
module.Support for other synchronization primitives is planned.
use tracing_mutex::stdsync::Mutex;let some_mutex =Mutex::new(42);*some_mutex.lock().unwrap() +=1;println!("{:?}", some_mutex);
The interdependencies between locks are automatically tracked. If any locking operation wouldintroduce a cyclic dependency between your locks, the operation panics instead. This allows you toimmediately notice the cyclic dependency rather than be eventually surprised by it in production.
Mutex tracing is efficient, but it is not completely overhead-free. If you cannot spare theperformance penalty in your production environment, this library also offers debug-only tracing. Thetype aliases intracing_mutex::stdsync
correspond to tracing primitives fromtracing_mutex::stdsync::tracing
when debug assertions are enabled, and to primitives fromstd::sync::Mutex
when they are not. A similar structure exists for other
The minimum supported Rust version is 1.70. Increasing this is not considered a breaking change, butwill be avoided within semver-compatible releases if possible.
- Dependency-tracking wrappers for all locking primitives
- Optional opt-out for release mode code
- Optional backtrace capture to aid with reproducing cyclic mutex chains
- Support for primitives from:
std::sync
parking_lot
- Any library that implements the
lock_api
traits
- Improve performance in lock tracing
- Better and configurable error handling when detecting cyclic dependencies
- Support for other locking libraries
- Support for async locking libraries
- Support for
Send
mutex guards
Note:parking_lot
has already began work on its own deadlock detection mechanism, which worksin a different way. Both can be complimentary.
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE orhttp://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT orhttp://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in thework by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without anyadditional terms or conditions.
About
A Mutex wrapper tracking acquisition order