Skip to main content

SharedBox

Struct SharedBox 

Source
pub struct SharedBox<T: ?Sized> { /* private fields */ }
Expand description

A structure owning the original Box which can be used to create multiple SharedBoxRef to send to other thread. It uses a counter to record the number of SharedBoxRef that has been created and not given back.

Dropping SharedBox without returning all SharedBoxRef that it has created leaks its heap memory. When panic-on-drop feature is enabled, it will panic:

let r = {
    let mut b = manual_share::SharedBox::new(0);
    b.borrow()

    // dropping SharedBox, panic here
};
println!("{}", r.get());

When all SharedBoxRef have been returned back to SharedBox, it will free and properly release its heap memory when SharedBox is dropped.

let mut b = manual_share::SharedBox::new(0);
let r = b.borrow();
b.try_return(r).unwrap();

// Dropping SharedBox here will free the heap memory it owns. No panic will occur.

Implementations§

Source§

impl<T> SharedBox<T>

Source

pub fn new(value: T) -> Self

Create a SharedBox by creating a Box first, then convert it to a SharedBox.

Source§

impl<T: ?Sized> SharedBox<T>

Source

pub fn from_box(unique: Box<T>) -> Self

Create a SharedBox by consuming a Box.

Source

pub fn borrow(&mut self) -> SharedBoxRef<T>

Create a SharedBoxRef and increase the borrow count.

§panics

Panics when borrow count overflows usize.

Source

pub fn try_return( &mut self, reference: SharedBoxRef<T>, ) -> Result<(), SharedBoxRef<T>>

Try to return back the SharedBoxRef. Returns Err if the SharedBoxRef does not originate from the same SharedBox.

Decrease the borrow count if not error occurs.

use manual_share::SharedBox;

let mut b1 = SharedBox::from_box(Box::new(8));
let r1 = b1.borrow();
b1.try_return(r1).unwrap();

let mut b2 = SharedBox::from_box(Box::new(9));
let r2 = b2.borrow();

// Giving SharedBoxRef to the wrong SharedBox returns Err.
let r2 = b1.try_return(r2).unwrap_err();

b2.try_return(r2).unwrap();
Source

pub fn try_into_box(self) -> Result<Box<T>, Self>

Try to convert Self into a Box if all borrowed SharedBoxRef has been given back.

use manual_share::SharedBox;

let b = Box::new(0);
let mut b = SharedBox::from_box(b);

let r = b.borrow();

// Try to convert to Box without returning all SharedBoxRef returns Err.
let mut b = b.try_into_box().unwrap_err();

b.try_return(r).unwrap();

let b = b.try_into_box().unwrap();
assert_eq!(b, Box::new(0));
Source

pub fn get(&self) -> &T

Directly get a reference to the value inside the SharedBox. This use rust built-in lifetime check to ensure the reference is valid as long as the SharedBox is alive, and has no runtime overhead.

Trait Implementations§

Source§

impl<T: Debug + ?Sized> Debug for SharedBox<T>

Source§

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

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

impl<T: ?Sized> Drop for SharedBox<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<T: Send + Sync> Send for SharedBox<T>

See https://users.rust-lang.org/t/built-a-crate-to-safely-share-box-and-vec-manually/141138/25?u=newdino for why it require Sync.

Source§

impl<T: Sync> Sync for SharedBox<T>

Auto Trait Implementations§

§

impl<T> Freeze for SharedBox<T>
where T: ?Sized,

§

impl<T> RefUnwindSafe for SharedBox<T>
where T: RefUnwindSafe + ?Sized,

§

impl<T> Unpin for SharedBox<T>
where T: ?Sized,

§

impl<T> UnsafeUnpin for SharedBox<T>
where T: ?Sized,

§

impl<T> UnwindSafe for SharedBox<T>
where T: RefUnwindSafe + ?Sized,

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.