1
0
Fork 0
mirror of https://forgejo.ellis.link/continuwuation/continuwuity.git synced 2025-07-27 18:28:31 +00:00
continuwuity/src/core/utils/with_lock.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

90 lines
2.3 KiB
Rust
Raw Normal View History

2025-07-01 23:57:24 +01:00
//! Traits for explicitly scoping the lifetime of locks.
use std::sync::{Arc, Mutex};
pub trait WithLock<T: ?Sized> {
2025-07-01 23:57:24 +01:00
/// Acquires a lock and executes the given closure with the locked data.
fn with_lock<F>(&self, f: F)
where
F: FnMut(&mut T);
}
impl<T> WithLock<T> for Mutex<T> {
fn with_lock<F>(&self, mut f: F)
where
F: FnMut(&mut T),
{
// The locking and unlocking logic is hidden inside this function.
let mut data_guard = self.lock().unwrap();
f(&mut data_guard);
// Lock is released here when `data_guard` goes out of scope.
}
}
impl<T> WithLock<T> for Arc<Mutex<T>> {
fn with_lock<F>(&self, mut f: F)
where
F: FnMut(&mut T),
{
// The locking and unlocking logic is hidden inside this function.
let mut data_guard = self.lock().unwrap();
f(&mut data_guard);
// Lock is released here when `data_guard` goes out of scope.
}
}
impl<R: lock_api::RawMutex, T: ?Sized> WithLock<T> for lock_api::Mutex<R, T> {
fn with_lock<F>(&self, mut f: F)
where
F: FnMut(&mut T),
{
// The locking and unlocking logic is hidden inside this function.
let mut data_guard = self.lock();
f(&mut data_guard);
// Lock is released here when `data_guard` goes out of scope.
}
}
impl<R: lock_api::RawMutex, T: ?Sized> WithLock<T> for Arc<lock_api::Mutex<R, T>> {
fn with_lock<F>(&self, mut f: F)
where
F: FnMut(&mut T),
{
// The locking and unlocking logic is hidden inside this function.
let mut data_guard = self.lock();
f(&mut data_guard);
// Lock is released here when `data_guard` goes out of scope.
}
}
2025-07-01 23:57:24 +01:00
pub trait WithLockAsync<T> {
/// Acquires a lock and executes the given closure with the locked data.
fn with_lock<F>(&self, f: F) -> impl Future<Output = ()>
where
F: FnMut(&mut T);
}
impl<T> WithLockAsync<T> for futures::lock::Mutex<T> {
async fn with_lock<F>(&self, mut f: F)
where
F: FnMut(&mut T),
{
// The locking and unlocking logic is hidden inside this function.
let mut data_guard = self.lock().await;
f(&mut data_guard);
// Lock is released here when `data_guard` goes out of scope.
}
}
impl<T> WithLockAsync<T> for Arc<futures::lock::Mutex<T>> {
async fn with_lock<F>(&self, mut f: F)
where
F: FnMut(&mut T),
{
// The locking and unlocking logic is hidden inside this function.
let mut data_guard = self.lock().await;
f(&mut data_guard);
// Lock is released here when `data_guard` goes out of scope.
}
}