summaryrefslogtreecommitdiff
path: root/src/collection/owned.rs
diff options
context:
space:
mode:
authorMica White <botahamec@outlook.com>2026-02-07 13:16:39 -0500
committerMica White <botahamec@outlook.com>2026-02-07 13:16:39 -0500
commit055e6fd92326e4796dccd13948b400719f65b546 (patch)
treea1b33f31a4820a3826a0ce59249c0f10e699648d /src/collection/owned.rs
parentc3a33edff89e96343d6413e597891f9718d0088f (diff)
Finish documentation
Diffstat (limited to 'src/collection/owned.rs')
-rwxr-xr-xsrc/collection/owned.rs134
1 files changed, 134 insertions, 0 deletions
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<L: OwnedLockable> OwnedLockCollection<L> {
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<L: OwnedLockable> OwnedLockCollection<L> {
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<L: OwnedLockable> OwnedLockCollection<L> {
}
impl<L: Sharable> OwnedLockCollection<L> {
+ /// 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<L: Sharable> OwnedLockCollection<L> {
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,