From 055e6fd92326e4796dccd13948b400719f65b546 Mon Sep 17 00:00:00 2001 From: Mica White Date: Sat, 7 Feb 2026 13:16:39 -0500 Subject: Finish documentation --- src/collection/owned.rs | 134 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) (limited to 'src/collection/owned.rs') diff --git a/src/collection/owned.rs b/src/collection/owned.rs index 02d434c..456742b 100755 --- a/src/collection/owned.rs +++ b/src/collection/owned.rs @@ -189,6 +189,36 @@ impl OwnedLockCollection { Self { child: data } } + /// Acquires an exclusive lock, blocking until it is safe to do so, and then + /// unlocks after the provided function returns. + /// + /// This function is useful to ensure that the data is never accidentally + /// locked forever by leaking the guard. Even if the function panics, this + /// function will gracefully notice the panic, and unlock. This function + /// provides no guarantees with respect to the ordering of whether contentious + /// readers or writers will acquire the lock first. + /// + /// # Panics + /// + /// This function will panic if the provided function also panics. However, + /// the collection will be safely unlocked in this case, allowing the + /// collection to be locked again later. + /// + /// # Example + /// + /// ``` + /// use happylock::{ThreadKey, Mutex}; + /// use happylock::collection::OwnedLockCollection; + /// + /// let mut key = ThreadKey::get().unwrap(); + /// let data = (Mutex::new(0), Mutex::new("")); + /// let lock = OwnedLockCollection::new(data); + /// + /// lock.scoped_lock(&mut key, |(number, string)| { + /// *number += 1; + /// *string = "1"; + /// }); + /// ``` pub fn scoped_lock<'a, R>( &'a self, key: impl Keyable, @@ -197,6 +227,43 @@ impl OwnedLockCollection { scoped_write(self, key, f) } + /// Attempts to acquire an exclusive lock to the underlying data without + /// blocking, and then unlocks once the provided function returns. + /// + /// This function implements a non-blocking variant of [`scoped_lock`]. + /// Unlike `scoped_lock`, if the lock collection is not already unlocked, then + /// the provided function will not run, and the given [`Keyable`] is returned. + /// This method does not provide any guarantees with respect to the ordering + /// of whether contentious readers or writers will acquire the lock first. + /// + /// # Errors + /// + /// If any of the locks in the collection are already locked, then the + /// provided function will not run. `Err` is returned with the given key. + /// + /// # Panics + /// + /// This function will panic if the provided function also panics. However, + /// the collection will be safely unlocked in this case, allowing the + /// collection to be locked again later. + /// + /// # Example + /// + /// ``` + /// use happylock::{ThreadKey, Mutex}; + /// use happylock::collection::OwnedLockCollection; + /// + /// let mut key = ThreadKey::get().unwrap(); + /// let data = (Mutex::new(0), Mutex::new("")); + /// let lock = OwnedLockCollection::new(data); + /// + /// lock.scoped_try_lock(&mut key, |(number, string)| { + /// *number += 1; + /// *string = "1"; + /// }).expect("This lock has not yet been locked"); + /// ``` + /// + /// [`scoped_lock`]: OwnedLockCollection::scoped_lock pub fn scoped_try_lock<'a, Key: Keyable, R>( &'a self, key: Key, @@ -308,6 +375,36 @@ impl OwnedLockCollection { } impl OwnedLockCollection { + /// Acquires a shared lock, blocking until it is safe to do so, and then + /// unlocks after the provided function returns. + /// + /// This function is useful to ensure that the data is never accidentally + /// locked forever by leaking the guard. Even if the function panics, this + /// function will gracefully notice the panic, and unlock. This function + /// provides no guarantees with respect to the ordering of whether contentious + /// readers or writers will acquire the lock first. + /// + /// # Panics + /// + /// This function will panic if the provided function also panics. However, + /// the collection will be safely unlocked in this case, allowing the + /// collection to be locked again later. + /// + /// # Example + /// + /// ``` + /// use happylock::{ThreadKey, RwLock}; + /// use happylock::collection::OwnedLockCollection; + /// + /// let mut key = ThreadKey::get().unwrap(); + /// let data = (RwLock::new(0), RwLock::new("")); + /// let lock = OwnedLockCollection::new(data); + /// + /// lock.scoped_read(&mut key, |(number, string)| { + /// assert_eq!(*number, 0); + /// assert_eq!(*string, ""); + /// }); + /// ``` pub fn scoped_read<'a, R>( &'a self, key: impl Keyable, @@ -316,6 +413,43 @@ impl OwnedLockCollection { scoped_read(self, key, f) } + /// Attempts to acquire an exclusive lock to the underlying data without + /// blocking, and then unlocks once the provided function returns. + /// + /// This function implements a non-blocking variant of [`scoped_read`]. + /// Unlike `scoped_read`, if the lock collection is exclusively locked, then + /// the provided function will not run, and the given [`Keyable`] is returned. + /// This method does not provide any guarantees with respect to the ordering + /// of whether contentious readers or writers will acquire the lock first. + /// + /// # Errors + /// + /// If any of the locks in the collection are already exclusively locked, then + /// the provided function will not run. `Err` is returned with the given key. + /// + /// # Panics + /// + /// This function will panic if the provided function also panics. However, + /// the collection will be safely unlocked in this case, allowing the + /// collection to be locked again later. + /// + /// # Example + /// + /// ``` + /// use happylock::{ThreadKey, RwLock}; + /// use happylock::collection::OwnedLockCollection; + /// + /// let mut key = ThreadKey::get().unwrap(); + /// let data = (RwLock::new(0), RwLock::new("")); + /// let lock = OwnedLockCollection::new(data); + /// + /// lock.scoped_try_read(&mut key, |(number, string)| { + /// assert_eq!(*number, 0); + /// assert_eq!(*string, ""); + /// }).expect("This lock has not yet been locked"); + /// ``` + /// + /// [`scoped_read`]: OwnedLockCollection::scoped_read pub fn scoped_try_read<'a, Key: Keyable, R>( &'a self, key: Key, -- cgit v1.2.3