tracing_mutex/util.rs
1//! Utilities related to the internals of dependency tracking.
2use crate::MutexId;
3
4/// Reset the dependencies for the given entity.
5///
6/// # Performance
7///
8/// This function locks the dependency graph to remove the item from it. This is an `O(E)` operation
9/// with `E` being the number of dependencies directly associated with this particular instance. As
10/// such, it is not advisable to call this method from a hot loop.
11///
12/// # Safety
13///
14/// Use of this method invalidates the deadlock prevention guarantees that this library makes. As
15/// such, it should only be used when it is absolutely certain this will not introduce deadlocks
16/// later.
17///
18/// Other than deadlocks, no undefined behaviour can result from the use of this function.
19///
20/// # Example
21///
22/// ```
23/// use tracing_mutex::stdsync::Mutex;
24/// use tracing_mutex::util;
25///
26/// let first = Mutex::new(());
27/// let second = Mutex::new(());
28///
29/// {
30/// let _first_lock = first.lock().unwrap();
31/// second.lock().unwrap();
32/// }
33///
34/// // Reset the dependencies for the first mutex
35/// unsafe { util::reset_dependencies(&first) };
36///
37/// // Now we can unlock the mutexes in the opposite order without a panic.
38/// let _second_lock = second.lock().unwrap();
39/// first.lock().unwrap();
40/// ```
41#[cfg(feature = "experimental")]
42#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
43pub unsafe fn reset_dependencies<T: Traced>(traced: &T) {
44 crate::get_dependency_graph().remove_node(traced.get_id().value());
45}
46
47/// Types that participate in dependency tracking
48///
49/// This trait is a public marker trait and is automatically implemented fore all types that
50/// implement the internal dependency tracking features.
51#[cfg(feature = "experimental")]
52#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
53#[allow(private_bounds)]
54pub trait Traced: PrivateTraced {}
55
56#[cfg(feature = "experimental")]
57#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
58impl<T: PrivateTraced> Traced for T {}
59
60/// Private implementation of the traced marker.
61///
62/// This trait is private (and seals the outer trait) to avoid exposing the MutexId type.
63#[cfg_attr(not(feature = "experimental"), allow(unused))]
64pub(crate) trait PrivateTraced {
65 /// Get the mutex id associated with this traced item.
66 fn get_id(&self) -> &MutexId;
67}