From 1aa891c0537603513ae185ad54fab4b017e07cfb Mon Sep 17 00:00:00 2001 From: Jade Ellis Date: Tue, 1 Jul 2025 23:57:24 +0100 Subject: [PATCH] refactor: Add with_lock traits --- src/core/utils/mod.rs | 1 + src/core/utils/with_lock.rs | 65 +++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 src/core/utils/with_lock.rs diff --git a/src/core/utils/mod.rs b/src/core/utils/mod.rs index 54404e4c..329e2ea2 100644 --- a/src/core/utils/mod.rs +++ b/src/core/utils/mod.rs @@ -19,6 +19,7 @@ pub mod sys; #[cfg(test)] mod tests; pub mod time; +pub mod with_lock; pub use ::conduwuit_macros::implement; pub use ::ctor::{ctor, dtor}; diff --git a/src/core/utils/with_lock.rs b/src/core/utils/with_lock.rs new file mode 100644 index 00000000..76f014d1 --- /dev/null +++ b/src/core/utils/with_lock.rs @@ -0,0 +1,65 @@ +//! Traits for explicitly scoping the lifetime of locks. + +use std::sync::{Arc, Mutex}; + +pub trait WithLock { + /// Acquires a lock and executes the given closure with the locked data. + fn with_lock(&self, f: F) + where + F: FnMut(&mut T); +} + +impl WithLock for Mutex { + fn with_lock(&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 WithLock for Arc> { + fn with_lock(&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. + } +} + +pub trait WithLockAsync { + /// Acquires a lock and executes the given closure with the locked data. + fn with_lock(&self, f: F) -> impl Future + where + F: FnMut(&mut T); +} + +impl WithLockAsync for futures::lock::Mutex { + async fn with_lock(&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 WithLockAsync for Arc> { + async fn with_lock(&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. + } +}