add try_lock to MutexMap; allow TryFrom constructions
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
49023aa295
commit
7c0c029a4a
4 changed files with 71 additions and 19 deletions
|
@ -725,7 +725,7 @@ pub(super) async fn force_set_room_state_from_server(
|
|||
.save_state(room_id.clone().as_ref(), new_room_state)
|
||||
.await?;
|
||||
|
||||
let state_lock = self.services.rooms.state.mutex.lock(&room_id).await;
|
||||
let state_lock = self.services.rooms.state.mutex.lock(&*room_id).await;
|
||||
self.services
|
||||
.rooms
|
||||
.state
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
use std::{fmt::Debug, hash::Hash, sync::Arc};
|
||||
use std::{
|
||||
fmt::Debug,
|
||||
hash::Hash,
|
||||
sync::{Arc, TryLockError::WouldBlock},
|
||||
};
|
||||
|
||||
use tokio::sync::OwnedMutexGuard as Omg;
|
||||
|
||||
use crate::{err, Result};
|
||||
|
||||
/// Map of Mutexes
|
||||
pub struct MutexMap<Key, Val> {
|
||||
map: Map<Key, Val>,
|
||||
|
@ -30,16 +36,17 @@ where
|
|||
}
|
||||
|
||||
#[tracing::instrument(level = "trace", skip(self))]
|
||||
pub async fn lock<K>(&self, k: &K) -> Guard<Key, Val>
|
||||
pub async fn lock<'a, K>(&'a self, k: &'a K) -> Guard<Key, Val>
|
||||
where
|
||||
K: Debug + Send + ?Sized + Sync,
|
||||
Key: for<'a> From<&'a K>,
|
||||
Key: TryFrom<&'a K>,
|
||||
<Key as TryFrom<&'a K>>::Error: Debug,
|
||||
{
|
||||
let val = self
|
||||
.map
|
||||
.lock()
|
||||
.expect("locked")
|
||||
.entry(k.into())
|
||||
.entry(k.try_into().expect("failed to construct key"))
|
||||
.or_default()
|
||||
.clone();
|
||||
|
||||
|
@ -49,6 +56,51 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "trace", skip(self))]
|
||||
pub fn try_lock<'a, K>(&self, k: &'a K) -> Result<Guard<Key, Val>>
|
||||
where
|
||||
K: Debug + Send + ?Sized + Sync,
|
||||
Key: TryFrom<&'a K>,
|
||||
<Key as TryFrom<&'a K>>::Error: Debug,
|
||||
{
|
||||
let val = self
|
||||
.map
|
||||
.lock()
|
||||
.expect("locked")
|
||||
.entry(k.try_into().expect("failed to construct key"))
|
||||
.or_default()
|
||||
.clone();
|
||||
|
||||
Ok(Guard::<Key, Val> {
|
||||
map: Arc::clone(&self.map),
|
||||
val: val.try_lock_owned().map_err(|_| err!("would yield"))?,
|
||||
})
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "trace", skip(self))]
|
||||
pub fn try_try_lock<'a, K>(&self, k: &'a K) -> Result<Guard<Key, Val>>
|
||||
where
|
||||
K: Debug + Send + ?Sized + Sync,
|
||||
Key: TryFrom<&'a K>,
|
||||
<Key as TryFrom<&'a K>>::Error: Debug,
|
||||
{
|
||||
let val = self
|
||||
.map
|
||||
.try_lock()
|
||||
.map_err(|e| match e {
|
||||
| WouldBlock => err!("would block"),
|
||||
| _ => panic!("{e:?}"),
|
||||
})?
|
||||
.entry(k.try_into().expect("failed to construct key"))
|
||||
.or_default()
|
||||
.clone();
|
||||
|
||||
Ok(Guard::<Key, Val> {
|
||||
map: Arc::clone(&self.map),
|
||||
val: val.try_lock_owned().map_err(|_| err!("would yield"))?,
|
||||
})
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn contains(&self, k: &Key) -> bool { self.map.lock().expect("locked").contains_key(k) }
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue