Struct BoxedLockCollection

Source
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>

Source

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);
Source

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>

Source

pub fn new(data: 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(data);
Source§

impl<'a, L: OwnedLockable> BoxedLockCollection<&'a L>

Source

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>

Source

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) };
Source

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();
Source

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";
Source

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!(),
};
Source

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>

Source

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, "");
Source

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!(),
};
Source

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>

Source

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>

Source

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>

Source§

fn as_ref(&self) -> &T

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl<L: Debug> Debug for BoxedLockCollection<L>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<L: OwnedLockable + Default> Default for BoxedLockCollection<L>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<L> Drop for BoxedLockCollection<L>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<L: OwnedLockable> From<L> for BoxedLockCollection<L>

Source§

fn from(value: L) -> Self

Converts to this type from the input type.
Source§

impl<L: OwnedLockable, I: FromIterator<L> + OwnedLockable> FromIterator<L> for BoxedLockCollection<I>

Source§

fn from_iter<T: IntoIterator<Item = L>>(iter: T) -> Self

Creates a value from an iterator. Read more
Source§

impl<'a, L> IntoIterator for &'a BoxedLockCollection<L>

Source§

type Item = <&'a L as IntoIterator>::Item

The type of the elements being iterated over.
Source§

type IntoIter = <&'a L as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<L> IntoIterator for BoxedLockCollection<L>
where L: IntoIterator,

Source§

type Item = <L as IntoIterator>::Item

The type of the elements being iterated over.
Source§

type IntoIter = <L as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<L: Lockable> Lockable for BoxedLockCollection<L>

Source§

type Guard<'g> = <L as Lockable>::Guard<'g> where Self: 'g

The exclusive guard that does not hold a key
Source§

fn get_ptrs<'a>(&'a self, ptrs: &mut Vec<&'a dyn RawLock>)

Yields a list of references to the RawLocks contained within this value. Read more
Source§

unsafe fn guard(&self) -> Self::Guard<'_>

Returns a guard that can be used to access the underlying data mutably. Read more
Source§

impl<L: LockableIntoInner> LockableIntoInner for BoxedLockCollection<L>

Source§

type Inner = <L as LockableIntoInner>::Inner

The inner type that is behind the lock
Source§

fn into_inner(self) -> Self::Inner

Consumes the lock, returning the underlying the lock.
Source§

impl<L: Lockable> RawLock for BoxedLockCollection<L>

Source§

fn poison(&self)

Causes all subsequent calls to the lock function on this lock to panic. This does not affect anything currently holding the lock.
Source§

unsafe fn raw_lock(&self)

Blocks until the lock is acquired Read more
Source§

unsafe fn raw_try_lock(&self) -> bool

Attempt to lock without blocking. Read more
Source§

unsafe fn raw_unlock(&self)

Releases the lock Read more
Source§

unsafe fn raw_read(&self)

Blocks until the data the lock protects can be safely read. Read more
Source§

unsafe fn raw_try_read(&self) -> bool

Returns true if successful, false otherwise. Read more
Source§

unsafe fn raw_unlock_read(&self)

Releases the lock after calling read. Read more
Source§

impl<L: Sharable> Sharable for BoxedLockCollection<L>

Source§

type ReadGuard<'g> = <L as Sharable>::ReadGuard<'g> where Self: 'g

The shared guard type that does not hold a key
Source§

unsafe fn read_guard(&self) -> Self::ReadGuard<'_>

Returns a guard that can be used to immutably access the underlying data. Read more
Source§

impl<L: OwnedLockable> OwnedLockable for BoxedLockCollection<L>

Source§

impl<L: Send> Send for BoxedLockCollection<L>

Source§

impl<L: Sync> Sync for BoxedLockCollection<L>

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.