mirror of
https://github.com/bertptrs/tracing-mutex.git
synced 2025-12-25 12:40:31 +01:00
Add new reset_dependencies API
This commit is contained in:
@@ -99,6 +99,7 @@ pub mod lockapi;
|
|||||||
pub mod parkinglot;
|
pub mod parkinglot;
|
||||||
mod reporting;
|
mod reporting;
|
||||||
pub mod stdsync;
|
pub mod stdsync;
|
||||||
|
pub mod util;
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
/// Stack to track which locks are held
|
/// Stack to track which locks are held
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ use lock_api::RawRwLockUpgradeDowngrade;
|
|||||||
use lock_api::RawRwLockUpgradeFair;
|
use lock_api::RawRwLockUpgradeFair;
|
||||||
use lock_api::RawRwLockUpgradeTimed;
|
use lock_api::RawRwLockUpgradeTimed;
|
||||||
|
|
||||||
|
use crate::util::PrivateTraced;
|
||||||
use crate::LazyMutexId;
|
use crate::LazyMutexId;
|
||||||
|
use crate::MutexId;
|
||||||
|
|
||||||
/// Tracing wrapper for all [`lock_api`] traits.
|
/// Tracing wrapper for all [`lock_api`] traits.
|
||||||
///
|
///
|
||||||
@@ -86,6 +88,12 @@ impl<T> TracingWrapper<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> PrivateTraced for TracingWrapper<T> {
|
||||||
|
fn get_id(&self) -> &MutexId {
|
||||||
|
&self.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe impl<T> RawMutex for TracingWrapper<T>
|
unsafe impl<T> RawMutex for TracingWrapper<T>
|
||||||
where
|
where
|
||||||
T: RawMutex,
|
T: RawMutex,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use std::sync::TryLockResult;
|
|||||||
use std::sync::WaitTimeoutResult;
|
use std::sync::WaitTimeoutResult;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use crate::util::PrivateTraced;
|
||||||
use crate::BorrowedMutex;
|
use crate::BorrowedMutex;
|
||||||
use crate::LazyMutexId;
|
use crate::LazyMutexId;
|
||||||
|
|
||||||
@@ -127,6 +128,12 @@ impl<T> Mutex<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> PrivateTraced for Mutex<T> {
|
||||||
|
fn get_id(&self) -> &crate::MutexId {
|
||||||
|
&self.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> From<T> for Mutex<T> {
|
impl<T> From<T> for Mutex<T> {
|
||||||
fn from(t: T) -> Self {
|
fn from(t: T) -> Self {
|
||||||
Self::new(t)
|
Self::new(t)
|
||||||
@@ -375,6 +382,12 @@ impl<T> RwLock<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> PrivateTraced for RwLock<T> {
|
||||||
|
fn get_id(&self) -> &crate::MutexId {
|
||||||
|
&self.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> From<T> for RwLock<T> {
|
impl<T> From<T> for RwLock<T> {
|
||||||
fn from(t: T) -> Self {
|
fn from(t: T) -> Self {
|
||||||
Self::new(t)
|
Self::new(t)
|
||||||
@@ -455,6 +468,12 @@ impl Once {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PrivateTraced for Once {
|
||||||
|
fn get_id(&self) -> &crate::MutexId {
|
||||||
|
&self.mutex_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Wrapper for [`std::sync::OnceLock`]
|
/// Wrapper for [`std::sync::OnceLock`]
|
||||||
///
|
///
|
||||||
/// The exact locking behaviour of [`std::sync::OnceLock`] is currently undefined, but may
|
/// The exact locking behaviour of [`std::sync::OnceLock`] is currently undefined, but may
|
||||||
@@ -553,6 +572,12 @@ impl<T> OnceLock<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> PrivateTraced for OnceLock<T> {
|
||||||
|
fn get_id(&self) -> &crate::MutexId {
|
||||||
|
&self.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> Default for OnceLock<T> {
|
impl<T> Default for OnceLock<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
|||||||
59
src/util.rs
Normal file
59
src/util.rs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
use crate::MutexId;
|
||||||
|
|
||||||
|
/// Reset the dependencies for the given entity.
|
||||||
|
///
|
||||||
|
/// # Performance
|
||||||
|
///
|
||||||
|
/// This function locks the dependency graph to remove the item from it. This is an `O(E)` operation
|
||||||
|
/// with `E` being the number of dependencies directly associated with this particular instance. As
|
||||||
|
/// such, it is not advisable to call this method from a hot loop.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Use of this method invalidates the deadlock prevention guarantees that this library makes. As
|
||||||
|
/// such, it should only be used when it is absolutely certain this will not introduce deadlocks
|
||||||
|
/// later.
|
||||||
|
///
|
||||||
|
/// Other than deadlocks, no undefined behaviour can result from the use of this function.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use tracing_mutex::stdsync::Mutex;
|
||||||
|
/// use tracing_mutex::util;
|
||||||
|
///
|
||||||
|
/// let first = Mutex::new(());
|
||||||
|
/// let second = Mutex::new(());
|
||||||
|
///
|
||||||
|
/// {
|
||||||
|
/// let _first_lock = first.lock().unwrap();
|
||||||
|
/// second.lock().unwrap();
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // Reset the dependencies for the first mutex
|
||||||
|
/// unsafe { util::reset_dependencies(&first) };
|
||||||
|
///
|
||||||
|
/// // Now we can unlock the mutexes in the opposite order without a panic.
|
||||||
|
/// let _second_lock = second.lock().unwrap();
|
||||||
|
/// first.lock().unwrap();
|
||||||
|
/// ```
|
||||||
|
pub unsafe fn reset_dependencies<T: Traced>(traced: &T) {
|
||||||
|
crate::get_dependency_graph().remove_node(traced.get_id().value());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Types that participate in dependency tracking
|
||||||
|
///
|
||||||
|
/// This trait is a public marker trait and is automatically implemented fore all types that
|
||||||
|
/// implement the internal dependency tracking features.
|
||||||
|
#[allow(private_bounds)]
|
||||||
|
pub trait Traced: PrivateTraced {}
|
||||||
|
|
||||||
|
impl<T: PrivateTraced> Traced for T {}
|
||||||
|
|
||||||
|
/// Private implementation of the traced marker.
|
||||||
|
///
|
||||||
|
/// This trait is private (and seals the outer trait) to avoid exposing the MutexId type.
|
||||||
|
pub(crate) trait PrivateTraced {
|
||||||
|
/// Get the mutex id associated with this traced item.
|
||||||
|
fn get_id(&self) -> &MutexId;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user