more setvalue fixes and concurrency cleanup
This commit is contained in:
@@ -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))
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user