more setvalue fixes and concurrency cleanup

This commit is contained in:
Christien Rioux
2023-09-09 18:35:25 -04:00
parent 853976789f
commit 07f92b6e3f
12 changed files with 168 additions and 90 deletions

View File

@@ -135,4 +135,35 @@ where
// Return the locked guard
AsyncTagLockGuard::new(self.clone(), tag, guard)
}
pub fn try_lock_tag(&self, tag: T) -> Option<AsyncTagLockGuard<T>> {
// Get or create a tag lock entry
let mutex = {
let mut inner = self.inner.lock();
// See if this tag is in the table
// and if not, add a new mutex for this tag
let entry = inner
.table
.entry(tag.clone())
.or_insert_with(|| AsyncTagLockTableEntry {
mutex: Arc::new(AsyncMutex::new(())),
waiters: 0,
});
// Increment the number of waiters
entry.waiters += 1;
// Return the mutex associated with the tag
entry.mutex.clone()
// Drop the table guard
};
// Lock the tag lock
let opt_guard = asyncmutex_try_lock_arc!(mutex);
// Return the locked guard
opt_guard.map(|guard| AsyncTagLockGuard::new(self.clone(), tag, guard))
}
}

View File

@@ -55,6 +55,29 @@ pub async fn test_simple_single_contention() {
assert_eq!(table.len(), 1);
}
pub async fn test_simple_try() {
info!("test_simple_try");
let table = AsyncTagLockTable::new();
let a1 = SocketAddr::new("1.2.3.4".parse().unwrap(), 1234);
let a2 = SocketAddr::new("1.2.3.5".parse().unwrap(), 1235);
{
let _g1 = table.lock_tag(a1).await;
let opt_g2 = table.try_lock_tag(a1);
let opt_g3 = table.try_lock_tag(a2);
assert!(opt_g2.is_none());
assert!(opt_g3.is_some());
}
let opt_g4 = table.try_lock_tag(a1);
assert!(opt_g4.is_some());
assert_eq!(table.len(), 1);
}
pub async fn test_simple_double_contention() {
info!("test_simple_double_contention");
@@ -153,6 +176,7 @@ pub async fn test_parallel_single_contention() {
pub async fn test_all() {
test_simple_no_contention().await;
test_simple_try().await;
test_simple_single_contention().await;
test_parallel_single_contention().await;
}

View File

@@ -47,6 +47,13 @@ cfg_if::cfg_if! {
$x.clone().lock_owned().await
};
}
#[macro_export]
macro_rules! asyncmutex_try_lock_arc {
($x:expr) => {
$x.try_lock_owned().ok()
};
}
} else {
#[macro_export]
macro_rules! asyncmutex_try_lock {
@@ -60,6 +67,12 @@ cfg_if::cfg_if! {
$x.lock_arc().await
};
}
#[macro_export]
macro_rules! asyncmutex_try_lock_arc {
($x:expr) => {
$x.try_lock_arc()
};
}
}
}