{"id":13672314,"url":"https://github.com/bertptrs/tracing-mutex","last_synced_at":"2025-04-04T18:04:00.353Z","repository":{"id":36971027,"uuid":"340940326","full_name":"bertptrs/tracing-mutex","owner":"bertptrs","description":"A Mutex wrapper tracking acquisition order","archived":false,"fork":false,"pushed_at":"2025-03-10T21:12:46.000Z","size":159,"stargazers_count":69,"open_issues_count":5,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-28T17:08:27.535Z","etag":null,"topics":["concurrency","locking","rust"],"latest_commit_sha":null,"homepage":"https://docs.rs/tracing-mutex/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bertptrs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-21T15:55:56.000Z","updated_at":"2025-03-21T11:53:06.000Z","dependencies_parsed_at":"2025-03-10T18:40:21.861Z","dependency_job_id":null,"html_url":"https://github.com/bertptrs/tracing-mutex","commit_stats":{"total_commits":78,"total_committers":3,"mean_commits":26.0,"dds":0.07692307692307687,"last_synced_commit":"8feedb09d280c17988815acdbab579a8a4a485e9"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertptrs%2Ftracing-mutex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertptrs%2Ftracing-mutex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertptrs%2Ftracing-mutex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bertptrs%2Ftracing-mutex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bertptrs","download_url":"https://codeload.github.com/bertptrs/tracing-mutex/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247226212,"owners_count":20904465,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["concurrency","locking","rust"],"created_at":"2024-08-02T09:01:32.081Z","updated_at":"2025-04-04T18:04:00.329Z","avatar_url":"https://github.com/bertptrs.png","language":"Rust","readme":"# Tracing Mutex\n\n[![Continuous integration](https://github.com/bertptrs/tracing-mutex/actions/workflows/ci.yml/badge.svg)](https://github.com/bertptrs/tracing-mutex/actions/workflows/ci.yml)\n[![Crates.io](https://img.shields.io/crates/v/tracing-mutex.svg)](https://crates.io/crates/tracing-mutex)\n[![Documentation](https://docs.rs/tracing-mutex/badge.svg)](https://docs.rs/tracing-mutex)\n\nAvoid deadlocks in your mutexes by acquiring them in a consistent order, or else.\n\n## Background\n\nIn any code that uses mutexes or locks, you quickly run into the possibility of deadlock. With just\ntwo mutexes `Foo` and `Bar` you can already deadlock, assuming one thread first locks `Foo` then\nattempts to get `Bar` and another first gets `Bar` then tries to get `Foo`. Now both threads are\nwaiting for each other to release the lock they already have.\n\nOne simple way to get around this is by ensuring that, when you need both `Foo` and `Bar`, you\nshould first acquire `Foo` then you can never deadlock. Of course, with just two mutexes, this is\neasy to keep track of, but once your code starts to grow you might lose track of all these\ndependencies. That's where this crate comes in.\n\nThis crate tracks the order in which you acquire locks in your code, tries to build a dependency\ntree out of it, and panics if your dependencies would create a cycle. It provides replacements for\nexisting synchronization primitives with an identical API, and should be a drop-in replacement.\n\nInspired by [this blogpost][whileydave], which references a similar behaviour implemented by\n[Abseil][abseil-mutex] for their mutexes. [This article goes into more depth on the exact\nimplementation.][article]\n\n[whileydave]: https://whileydave.com/2020/12/19/dynamic-cycle-detection-for-lock-ordering/\n[abseil-mutex]: https://abseil.io/docs/cpp/guides/synchronization\n[article]: https://bertptrs.nl/2022/06/23/deadlock-free-mutexes-and-directed-acyclic-graphs.html\n\n## Usage\n\nAdd this dependency to your `Cargo.lock` file like any other:\n\n```toml\n[dependencies]\ntracing-mutex = \"0.3\"\n```\n\nThen use the locks provided by this library instead of the ones you would use otherwise.\nReplacements for the synchronization primitives in `std::sync` can be found in the `stdsync` module.\nSupport for other synchronization primitives is planned.\n\n```rust\nuse tracing_mutex::stdsync::Mutex;\n\nlet some_mutex = Mutex::new(42);\n*some_mutex.lock().unwrap() += 1;\nprintln!(\"{:?}\", some_mutex);\n```\n\nThe interdependencies between locks are automatically tracked. If any locking operation would\nintroduce a cyclic dependency between your locks, the operation panics instead. This allows you to\nimmediately notice the cyclic dependency rather than be eventually surprised by it in production.\n\nMutex tracing is efficient, but it is not completely overhead-free. If you cannot spare the\nperformance penalty in your production environment, this library also offers debug-only tracing. The\ntype aliases in `tracing_mutex::stdsync` correspond to tracing primitives from\n`tracing_mutex::stdsync::tracing` when debug assertions are enabled, and to primitives from\n`std::sync::Mutex` when they are not. A similar structure exists for other \n\nThe minimum supported Rust version is 1.70. Increasing this is not considered a breaking change, but\nwill be avoided within semver-compatible releases if possible.\n\n### Features\n\n- Dependency-tracking wrappers for all locking primitives\n- Optional opt-out for release mode code\n- Optional backtrace capture to aid with reproducing cyclic mutex chains\n- Support for primitives from:\n  - `std::sync`\n  - `parking_lot`\n  - Any library that implements the `lock_api` traits\n\n## Future improvements\n\n- Improve performance in lock tracing\n- Better and configurable error handling when detecting cyclic dependencies\n- Support for other locking libraries\n- Support for async locking libraries\n- Support for `Send` mutex guards\n\n**Note:** `parking_lot` has already began work on its own deadlock detection mechanism, which works\nin a different way. Both can be complimentary.\n\n## License\n\nLicensed under either of\n\n- Apache License, Version 2.0, ([LICENSE-APACHE](./LICENSE-APACHE) or\n  http://www.apache.org/licenses/LICENSE-2.0)\n- MIT license ([LICENSE-MIT](./LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contributing\n\nUnless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the\nwork by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any\nadditional terms or conditions.\n","funding_links":[],"categories":["Rust"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbertptrs%2Ftracing-mutex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbertptrs%2Ftracing-mutex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbertptrs%2Ftracing-mutex/lists"}