diff --git a/crates/locksmith/src/common.rs b/crates/locksmith/src/common.rs index 90f8a96b8f..fb10aaa936 100644 --- a/crates/locksmith/src/common.rs +++ b/crates/locksmith/src/common.rs @@ -27,8 +27,15 @@ lazy_static! { type GuardsMap = HashMap; -pub(crate) fn guards_guard<'a>() -> MutexGuard<'a, GuardsMap> { +fn guards_guard<'a>() -> MutexGuard<'a, GuardsMap> { GUARDS .try_lock_for(Duration::from_secs(20)) .expect("Guard-tracking mutex has been locked up for 20 seconds!") } + +pub(crate) fn with_guards_guard<'a, T, F: FnOnce(&mut MutexGuard<'a, GuardsMap>) -> T>(f: F) -> T { + let mut g = guards_guard(); + let val = f(&mut g); + MutexGuard::unlock_fair(g); + val +} diff --git a/crates/locksmith/src/guard.rs b/crates/locksmith/src/guard.rs index b5ab4a0f65..80f8ea3112 100644 --- a/crates/locksmith/src/guard.rs +++ b/crates/locksmith/src/guard.rs @@ -1,4 +1,4 @@ -use crate::{common::guards_guard, error::LockType, tracker::GuardTracker}; +use crate::{common::with_guards_guard, error::LockType, tracker::GuardTracker}; use parking_lot::{MutexGuard, RwLockReadGuard, RwLockWriteGuard}; use snowflake::ProcessUniqueId; use std::{ @@ -17,7 +17,9 @@ macro_rules! guard_struct { impl<'a, T: ?Sized> $HcGuard<'a, T> { pub fn new(inner: $Guard<'a, T>) -> Self { let puid = ProcessUniqueId::new(); - guards_guard().insert(puid, GuardTracker::new(puid, LockType::$lock_type)); + with_guards_guard(|g| { + g.insert(puid, GuardTracker::new(puid, LockType::$lock_type)) + }); Self { puid, inner: Some(inner), @@ -28,9 +30,10 @@ macro_rules! guard_struct { /// Add some context which will output in the case that this guard /// lives to be an immortal pub fn annotate>(self, annotation: S) -> Self { - guards_guard() - .entry(self.puid) - .and_modify(|g| g.annotation = Some(annotation.into())); + with_guards_guard(|g| { + g.entry(self.puid) + .and_modify(|g| g.annotation = Some(annotation.into())); + }); self } @@ -56,7 +59,7 @@ macro_rules! guard_struct { impl<'a, T: ?Sized> Drop for $HcGuard<'a, T> { fn drop(&mut self) { - guards_guard().remove(&self.puid); + with_guards_guard(|g| g.remove(&self.puid)); if self.fair_unlocking { self._unlock_fair(); } diff --git a/crates/locksmith/src/sync.rs b/crates/locksmith/src/sync.rs index 405ebf33fc..73f1ca00cb 100644 --- a/crates/locksmith/src/sync.rs +++ b/crates/locksmith/src/sync.rs @@ -139,7 +139,6 @@ Backtrace at the moment of guard creation follows: } lazy_static! { - static ref GUARDS: Mutex> = Mutex::new(HashMap::new()); static ref PENDING_LOCKS: Mutex> = Mutex::new(HashMap::new()); } @@ -152,10 +151,10 @@ pub fn spawn_locksmith_guard_watcher() { )) .spawn(move || loop { let mut reports: Vec<(i64, String)> = { - guards_guard() + with_guards_guard(|g| g .values_mut() .filter_map(|gt| gt.report_and_update()) - .collect(); + .collect()); }; if reports.len() > 0 { reports.sort_unstable_by_key(|(elapsed, _)| -*elapsed); @@ -206,21 +205,21 @@ macro_rules! guard_struct { impl<'a, T: ?Sized> $HcGuard<'a, T> { pub fn new(inner: $Guard<'a, T>) -> Self { let puid = ProcessUniqueId::new(); - guards_guard().insert(puid, GuardTracker::new(puid, LockType::$lock_type)); + with_guards_guard(|g| g.insert(puid, GuardTracker::new(puid, LockType::$lock_type))); Self { puid, inner } } pub fn annotate>(self, annotation: S) -> Self { - guards_guard() + with_guards_guard(|g| g .entry(self.puid) - .and_modify(|g| g.annotation = Some(annotation.into())); + .and_modify(|g| g.annotation = Some(annotation.into()))); self } } impl<'a, T: ?Sized> Drop for $HcGuard<'a, T> { fn drop(&mut self) { - guards_guard().remove(&self.puid); + with_guards_guard(|g| g.remove(&self.puid)); } } }; diff --git a/crates/locksmith/src/tracker.rs b/crates/locksmith/src/tracker.rs index b9b6101631..a3f5bb78d1 100644 --- a/crates/locksmith/src/tracker.rs +++ b/crates/locksmith/src/tracker.rs @@ -1,6 +1,6 @@ use crate::{ common::{ - guards_guard, ACTIVE_GUARD_MIN_ELAPSED, ACTIVE_GUARD_NO_ACTIVITY_INTERVAL, + with_guards_guard, ACTIVE_GUARD_MIN_ELAPSED, ACTIVE_GUARD_NO_ACTIVITY_INTERVAL, GUARD_WATCHER_POLL_INTERVAL, IMMORTAL_TIMEOUT, }, error::LockType, @@ -101,10 +101,11 @@ pub fn spawn_locksmith_guard_watcher() { let mut inactive_for = Duration::from_millis(0); loop { let mut reports: Vec<(i64, String)> = { - guards_guard() - .values_mut() - .filter_map(|gt| gt.report_and_update()) - .collect() + with_guards_guard(|g| { + g.values_mut() + .filter_map(|gt| gt.report_and_update()) + .collect() + }) }; if reports.len() > 0 { inactive_for = Duration::from_millis(0);