pub struct BoxedLockCollection<L> { /* private fields */ }
Expand description
Locks a collection of locks, stored in the heap, by sorting them by memory address.
This could be a tuple of Lockable
types, an array, or a Vec
. But it
can be safely locked without causing a deadlock.
Upon construction, it must be confirmed that the collection contains no
duplicate locks. This can be done by either using OwnedLockable
or by
checking. Regardless of how this is done, the locks will be sorted by their
memory address before locking them. The sorted order of the locks is stored
within this collection.
Unlike RefLockCollection
, this is a self-referential type which boxes
the data that is given to it. This means no lifetimes are necessary on the
type itself, but it is slightly slower because of the memory allocation.
Implementations§
Source§impl<L> BoxedLockCollection<L>
impl<L> BoxedLockCollection<L>
Sourcepub fn into_child(self) -> L
pub fn into_child(self) -> L
Gets the underlying collection, consuming this collection.
§Examples
use happylock::{Mutex, ThreadKey, LockCollection};
let data1 = Mutex::new(42);
let data2 = Mutex::new("");
// data1 and data2 refer to distinct mutexes, so this won't panic
let data = (&data1, &data2);
let lock = LockCollection::try_new(&data).unwrap();
let key = ThreadKey::get().unwrap();
let guard = lock.into_child().0.lock(key);
assert_eq!(*guard, 42);
Sourcepub fn child(&self) -> &L
pub fn child(&self) -> &L
Gets an immutable reference to the underlying data
§Examples
use happylock::{Mutex, ThreadKey, LockCollection};
let data1 = Mutex::new(42);
let data2 = Mutex::new("");
// data1 and data2 refer to distinct mutexes, so this won't panic
let data = (&data1, &data2);
let lock = LockCollection::try_new(&data).unwrap();
let key = ThreadKey::get().unwrap();
let guard = lock.child().0.lock(key);
assert_eq!(*guard, 42);
Source§impl<L: OwnedLockable> BoxedLockCollection<L>
impl<L: OwnedLockable> BoxedLockCollection<L>
Source§impl<'a, L: OwnedLockable> BoxedLockCollection<&'a L>
impl<'a, L: OwnedLockable> BoxedLockCollection<&'a L>
Sourcepub fn new_ref(data: &'a L) -> Self
pub fn new_ref(data: &'a L) -> Self
Creates a new collection of owned locks.
Because the locks are owned, there’s no need to do any checks for duplicate values.
§Examples
use happylock::{Mutex, LockCollection};
let data = (Mutex::new(0), Mutex::new(""));
let lock = LockCollection::new_ref(&data);
Source§impl<L: Lockable> BoxedLockCollection<L>
impl<L: Lockable> BoxedLockCollection<L>
Sourcepub unsafe fn new_unchecked(data: L) -> Self
pub unsafe fn new_unchecked(data: L) -> Self
Creates a new collections of locks.
§Safety
This results in undefined behavior if any locks are presented twice within this collection.
§Examples
use happylock::{Mutex, LockCollection};
let data1 = Mutex::new(0);
let data2 = Mutex::new("");
// safety: data1 and data2 refer to distinct mutexes
let data = (&data1, &data2);
let lock = unsafe { LockCollection::new_unchecked(&data) };
Sourcepub fn try_new(data: L) -> Option<Self>
pub fn try_new(data: L) -> Option<Self>
Creates a new collection of locks.
This returns None
if any locks are found twice in the given
collection.
§Examples
use happylock::{Mutex, LockCollection};
let data1 = Mutex::new(0);
let data2 = Mutex::new("");
// data1 and data2 refer to distinct mutexes, so this won't panic
let data = (&data1, &data2);
let lock = LockCollection::try_new(&data).unwrap();
Sourcepub fn lock<'g, 'key: 'g, Key: Keyable + 'key>(
&'g self,
key: Key,
) -> LockGuard<'key, L::Guard<'g>, Key>
pub fn lock<'g, 'key: 'g, Key: Keyable + 'key>( &'g self, key: Key, ) -> LockGuard<'key, L::Guard<'g>, Key>
Locks the collection
This function returns a guard that can be used to access the underlying data. When the guard is dropped, the locks in the collection are also dropped.
§Examples
use happylock::{Mutex, ThreadKey, LockCollection};
let key = ThreadKey::get().unwrap();
let data = (Mutex::new(0), Mutex::new(""));
let lock = LockCollection::new(data);
let mut guard = lock.lock(key);
*guard.0 += 1;
*guard.1 = "1";
Sourcepub fn try_lock<'g, 'key: 'g, Key: Keyable + 'key>(
&'g self,
key: Key,
) -> Result<LockGuard<'key, L::Guard<'g>, Key>, Key>
pub fn try_lock<'g, 'key: 'g, Key: Keyable + 'key>( &'g self, key: Key, ) -> Result<LockGuard<'key, L::Guard<'g>, Key>, Key>
Attempts to lock the without blocking.
If the access could not be granted at this time, then Err
is
returned. Otherwise, an RAII guard is returned which will release the
locks when it is dropped.
§Errors
If any locks in the collection are already locked, then an error containing the given key is returned.
§Examples
use happylock::{Mutex, ThreadKey, LockCollection};
let key = ThreadKey::get().unwrap();
let data = (Mutex::new(0), Mutex::new(""));
let lock = LockCollection::new(data);
match lock.try_lock(key) {
Ok(mut guard) => {
*guard.0 += 1;
*guard.1 = "1";
},
Err(_) => unreachable!(),
};
Sourcepub fn unlock<'key, Key: Keyable + 'key>(
guard: LockGuard<'key, L::Guard<'_>, Key>,
) -> Key
pub fn unlock<'key, Key: Keyable + 'key>( guard: LockGuard<'key, L::Guard<'_>, Key>, ) -> Key
Unlocks the underlying lockable data type, returning the key that’s associated with it.
§Examples
use happylock::{Mutex, ThreadKey, LockCollection};
let key = ThreadKey::get().unwrap();
let data = (Mutex::new(0), Mutex::new(""));
let lock = LockCollection::new(data);
let mut guard = lock.lock(key);
*guard.0 += 1;
*guard.1 = "1";
let key = LockCollection::<(Mutex<i32>, Mutex<&str>)>::unlock(guard);
Source§impl<L: Sharable> BoxedLockCollection<L>
impl<L: Sharable> BoxedLockCollection<L>
Sourcepub fn read<'g, 'key: 'g, Key: Keyable + 'key>(
&'g self,
key: Key,
) -> LockGuard<'key, L::ReadGuard<'g>, Key>
pub fn read<'g, 'key: 'g, Key: Keyable + 'key>( &'g self, key: Key, ) -> LockGuard<'key, L::ReadGuard<'g>, Key>
Locks the collection, so that other threads can still read from it
This function returns a guard that can be used to access the underlying data immutably. When the guard is dropped, the locks in the collection are also dropped.
§Examples
use happylock::{RwLock, ThreadKey, LockCollection};
let key = ThreadKey::get().unwrap();
let data = (RwLock::new(0), RwLock::new(""));
let lock = LockCollection::new(data);
let mut guard = lock.read(key);
assert_eq!(*guard.0, 0);
assert_eq!(*guard.1, "");
Sourcepub fn try_read<'g, 'key: 'g, Key: Keyable + 'key>(
&'g self,
key: Key,
) -> Result<LockGuard<'key, L::ReadGuard<'g>, Key>, Key>
pub fn try_read<'g, 'key: 'g, Key: Keyable + 'key>( &'g self, key: Key, ) -> Result<LockGuard<'key, L::ReadGuard<'g>, Key>, Key>
Attempts to lock the without blocking, in such a way that other threads can still read from the collection.
If the access could not be granted at this time, then Err
is
returned. Otherwise, an RAII guard is returned which will release the
shared access when it is dropped.
§Errors
If any of the locks in the collection are already locked, then an error is returned containing the given key.
§Examples
use happylock::{RwLock, ThreadKey, LockCollection};
let key = ThreadKey::get().unwrap();
let data = (RwLock::new(5), RwLock::new("6"));
let lock = LockCollection::new(data);
match lock.try_read(key) {
Ok(mut guard) => {
assert_eq!(*guard.0, 5);
assert_eq!(*guard.1, "6");
},
Err(_) => unreachable!(),
};
Sourcepub fn unlock_read<'key, Key: Keyable + 'key>(
guard: LockGuard<'key, L::ReadGuard<'_>, Key>,
) -> Key
pub fn unlock_read<'key, Key: Keyable + 'key>( guard: LockGuard<'key, L::ReadGuard<'_>, Key>, ) -> Key
Unlocks the underlying lockable data type, returning the key that’s associated with it.
§Examples
use happylock::{RwLock, ThreadKey, LockCollection};
let key = ThreadKey::get().unwrap();
let data = (RwLock::new(0), RwLock::new(""));
let lock = LockCollection::new(data);
let mut guard = lock.read(key);
let key = LockCollection::<(RwLock<i32>, RwLock<&str>)>::unlock_read(guard);
Source§impl<L: LockableIntoInner> BoxedLockCollection<L>
impl<L: LockableIntoInner> BoxedLockCollection<L>
Sourcepub fn into_inner(self) -> <Self as LockableIntoInner>::Inner
pub fn into_inner(self) -> <Self as LockableIntoInner>::Inner
Consumes this BoxedLockCollection
, returning the underlying data.
§Examples
use happylock::{Mutex, LockCollection};
let mutex = LockCollection::new([Mutex::new(0), Mutex::new(0)]);
assert_eq!(mutex.into_inner(), [0, 0]);
Source§impl<'a, L: 'a> BoxedLockCollection<L>where
&'a L: IntoIterator,
impl<'a, L: 'a> BoxedLockCollection<L>where
&'a L: IntoIterator,
Sourcepub fn iter(&'a self) -> <&'a L as IntoIterator>::IntoIter
pub fn iter(&'a self) -> <&'a L as IntoIterator>::IntoIter
Returns an iterator over references to each value in the collection.
§Examples
use happylock::{Mutex, ThreadKey, LockCollection};
let key = ThreadKey::get().unwrap();
let data = [Mutex::new(26), Mutex::new(1)];
let lock = LockCollection::new(data);
let mut iter = lock.iter();
let mutex = iter.next().unwrap();
let guard = mutex.lock(key);
assert_eq!(*guard, 26);
Trait Implementations§
Source§impl<T, L: AsRef<T>> AsRef<T> for BoxedLockCollection<L>
impl<T, L: AsRef<T>> AsRef<T> for BoxedLockCollection<L>
Source§impl<L: Debug> Debug for BoxedLockCollection<L>
impl<L: Debug> Debug for BoxedLockCollection<L>
Source§impl<L: OwnedLockable + Default> Default for BoxedLockCollection<L>
impl<L: OwnedLockable + Default> Default for BoxedLockCollection<L>
Source§impl<L> Drop for BoxedLockCollection<L>
impl<L> Drop for BoxedLockCollection<L>
Source§impl<L: OwnedLockable> From<L> for BoxedLockCollection<L>
impl<L: OwnedLockable> From<L> for BoxedLockCollection<L>
Source§impl<L: OwnedLockable, I: FromIterator<L> + OwnedLockable> FromIterator<L> for BoxedLockCollection<I>
impl<L: OwnedLockable, I: FromIterator<L> + OwnedLockable> FromIterator<L> for BoxedLockCollection<I>
Source§fn from_iter<T: IntoIterator<Item = L>>(iter: T) -> Self
fn from_iter<T: IntoIterator<Item = L>>(iter: T) -> Self
Source§impl<'a, L> IntoIterator for &'a BoxedLockCollection<L>where
&'a L: IntoIterator,
impl<'a, L> IntoIterator for &'a BoxedLockCollection<L>where
&'a L: IntoIterator,
Source§impl<L> IntoIterator for BoxedLockCollection<L>where
L: IntoIterator,
impl<L> IntoIterator for BoxedLockCollection<L>where
L: IntoIterator,
Source§impl<L: Lockable> Lockable for BoxedLockCollection<L>
impl<L: Lockable> Lockable for BoxedLockCollection<L>
Source§impl<L: LockableIntoInner> LockableIntoInner for BoxedLockCollection<L>
impl<L: LockableIntoInner> LockableIntoInner for BoxedLockCollection<L>
Source§type Inner = <L as LockableIntoInner>::Inner
type Inner = <L as LockableIntoInner>::Inner
Source§fn into_inner(self) -> Self::Inner
fn into_inner(self) -> Self::Inner
Source§impl<L: Lockable> RawLock for BoxedLockCollection<L>
impl<L: Lockable> RawLock for BoxedLockCollection<L>
Source§fn poison(&self)
fn poison(&self)
lock
function on this lock to
panic. This does not affect anything currently holding the lock.Source§unsafe fn raw_try_lock(&self) -> bool
unsafe fn raw_try_lock(&self) -> bool
Source§unsafe fn raw_unlock(&self)
unsafe fn raw_unlock(&self)
Source§unsafe fn raw_read(&self)
unsafe fn raw_read(&self)
Source§unsafe fn raw_try_read(&self) -> bool
unsafe fn raw_try_read(&self) -> bool
Source§unsafe fn raw_unlock_read(&self)
unsafe fn raw_unlock_read(&self)
read
. Read more