parc

Struct ParentArc

Source
pub struct ParentArc<T> { /* private fields */ }
Expand description

Owner of multiple atomically reference counted children.

The type ParentArc<T> allows for shared access of the inner data by multiple threads through LockWeak references. Call downgrade on a ParentArc to create a child reference that can be upgraded into a temporary reader of the inner data. This allows for the locking and the consumption of the parent at any time because no strong references are held permanently.

Unlike Arc<T> this structure will die along with it’s readers.

§Thread Safety

The LockWeak can be passed around through threads safely because they do not guaranty the existence of the data at upgrade time. ParentArc<T> makes it thread safe to have multiple owned reference of the same data, but it doesn’t add thread safety to its data.

Implementations§

Source§

impl<T> ParentArc<T>

Source

pub fn new(data: T) -> Self

Build a new ParentArc

§Examples
use parc::ParentArc;
use std::sync::Mutex;
fn main() {
    let parent = ParentArc::new(Mutex::new(true));
}
Source

pub fn pin(data: T) -> Pin<ParentArc<T>>

Constructs a new Pin<ParentArc<T>>. If T does not implement Unpin, then data will be pinned in memory and unable to be moved.

Source

pub fn lock(&self)

Locks all LockWeak of this instance, it will prevent all further upgrades until unlocked. It is advised to call this before attempting a try_into_inner.

§Examples
use parc::ParentArc;
use std::sync::Mutex;
fn main() {
    let parent = ParentArc::new(Mutex::new(0));
    parent.lock(); // LockWeaks are no longer able to upgrade successfully
    assert!(parent.is_locked());
}
Source

pub fn is_locked(&self) -> bool

Check wether the LockWeaks are locked. Since only the Parent can unlock it is considered a somewhat trustable result.

Source

pub fn unlock(&self)

Unlocks all LockWeak of this ParentArc, this allows for their ugrade to start again.

§Examples
use parc::ParentArc;
use std::sync::Mutex;
fn main() {
    let parent = ParentArc::new(Mutex::new(0));
     
    parent.lock(); // LockWeaks are no longer able to upgrade successfully
    assert!(parent.is_locked());
     
    parent.unlock(); // LockWeaks can upgrade successfully again
    assert!(!parent.is_locked());
}
Source

pub fn downgrade(other: &Self) -> LockWeak<T>

Downgrade a ParentArc into a LockWeak

§Examples
use parc::{ParentArc, LockWeak};
use std::sync::Mutex;
fn main() {
    let parent = ParentArc::new(Mutex::new(true));
    let weak: LockWeak<_> = ParentArc::downgrade(&parent);
}
Source

pub fn try_downgrade(other: &Self) -> Option<LockWeak<T>>

Tries to downgrade a ParentArc into a LockWeak if the inner state allows the latter to upgrade.

§Examples
use parc::{ParentArc, LockWeak};
use std::sync::Mutex;
fn main() {
    let parent = ParentArc::new(Mutex::new(true));
    parent.lock(); // LockWeaks are no longer able to upgrade successfully
     
    if let Some(_) = ParentArc::try_downgrade(&parent) {
        assert!(false);
    }
}
Source

pub fn block_into_inner(self) -> T

Blocks the thread until all ChildArc of this instance have dropped, returning the underlying data.

§Safety

This call will indefinitly spin if a child has not droped correctly.

§Examples
use parc::{ParentArc, LockWeak};
use std::sync::Mutex;
fn main() {
    let parent = ParentArc::new(Mutex::new(true));
     
    let weak1: LockWeak<_> = ParentArc::downgrade(&parent);
    let weak2: LockWeak<_> = ParentArc::downgrade(&parent);
     
    let child = weak1.upgrade().unwrap();
    drop(child);

    let _: Mutex<bool> = parent.block_into_inner();
}
Source

pub fn try_unwrap(other: Self) -> TryUnwrapResult<T>

Non-blocking version of block_into_inner. It is advised to call lock before calling this one, unless you know for sure there are no ChildArc alive at this instance.

§Safety

This will never unwrap Ok(T) if a child has not droped correctly.

§Examples
use parc::{ParentArc, LockWeak, TryUnwrapError::*};
use std::sync::Mutex;
fn main() {
    let mut parent = ParentArc::new(Mutex::new(true));
     
    let weak1: LockWeak<_> = ParentArc::downgrade(&parent);
    let weak2: LockWeak<_> = ParentArc::downgrade(&parent);
     
    let child = weak1.upgrade().unwrap();
     
    // Unlocked LockWeaks
    parent = if let Err(WouldLock(parent)) = ParentArc::try_unwrap(parent) {
        parent
    } else {
        unreachable!()
    };

    // Locked LockWeaks
    parent.lock();
    parent = if let Err(WouldBlock(parent)) = ParentArc::try_unwrap(parent) {
        parent
    } else {
        unreachable!()
    };
    parent.unlock();

    // Droped children
    drop(child);
    let value: Mutex<bool> = ParentArc::try_unwrap(parent).unwrap();
}

Trait Implementations§

Source§

impl<T> AsRef<T> for ParentArc<T>

Source§

fn as_ref(&self) -> &T

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

impl<T> Deref for ParentArc<T>

Source§

type Target = T

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<T> Drop for ParentArc<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<T> Freeze for ParentArc<T>

§

impl<T> RefUnwindSafe for ParentArc<T>
where T: RefUnwindSafe,

§

impl<T> !Send for ParentArc<T>

§

impl<T> !Sync for ParentArc<T>

§

impl<T> Unpin for ParentArc<T>

§

impl<T> UnwindSafe for ParentArc<T>
where T: RefUnwindSafe,

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.