diff --git a/stratum-apps/src/custom_rw_lock.rs b/stratum-apps/src/custom_rw_lock.rs new file mode 100644 index 000000000..1f4b00dfb --- /dev/null +++ b/stratum-apps/src/custom_rw_lock.rs @@ -0,0 +1,63 @@ +//! A custom read write lock safe implementation + +use std::sync::{PoisonError, RwLock as InnerRwLock, RwLockReadGuard, RwLockWriteGuard}; + +/// A thin wrapper around [`std::sync::RwLock`] with an explicit locking policy. +/// +/// This type exists to provide clearer, more ergonomic locking APIs while +/// preserving the semantics of `std::sync::RwLock`. +/// +/// Higher-level methods on this type distinguish between: +/// - Scoped, closure-based access, which prevents lock guards from escaping +/// - Explicit guard-based access, for advanced use cases that require flexible control flow +#[derive(Debug)] +pub struct RwLock(InnerRwLock); + +impl RwLock { + /// Creates a new `RwLock` protecting `value`. + pub fn new(value: T) -> Self { + Self(InnerRwLock::new(value)) + } +} + +impl RwLock { + /// Executes `f` while holding a read lock. + /// + /// The lock guard cannot escape this method. + /// Prefer this over [`read`] for small, self-contained operations. + pub fn safe_read(&self, f: F) -> Result>> + where + F: FnOnce(&T) -> R, + { + let guard = self.0.read()?; + Ok(f(&*guard)) + } + + /// Executes `f` while holding a write lock. + /// + /// The lock guard cannot escape this method. + /// Poisoning is propagated to the caller. + pub fn safe_write(&self, f: F) -> Result>> + where + F: FnOnce(&mut T) -> R, + { + let mut guard = self.0.write()?; + Ok(f(&mut *guard)) + } + + /// Acquires a read lock and returns the guard directly. + /// + /// This is an API intended for complex control flow where + /// closure-based locking would harm readability. + pub fn read(&self) -> Result, PoisonError>> { + self.0.read() + } + + /// Acquires a write lock and returns the guard directly. + /// + /// Callers are responsible for keeping the + /// guard scope small and avoiding `.await` while holding it. + pub fn write(&self) -> Result, PoisonError>> { + self.0.write() + } +} diff --git a/stratum-apps/src/lib.rs b/stratum-apps/src/lib.rs index 7f5c7da4f..1e927afa3 100644 --- a/stratum-apps/src/lib.rs +++ b/stratum-apps/src/lib.rs @@ -46,6 +46,7 @@ pub mod config_helpers; /// /// A wrapper around std::sync::Mutex pub mod custom_mutex; +pub mod custom_rw_lock; /// RPC utilities for Job Declaration Server /// /// HTTP-based RPC server implementation for JD Server functionality.