ShmemBox

Struct ShmemBox 

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

A safe and typed wrapper for shared memory

ShmemBox<T> wraps the underlying pointer to the shared memory and implements Deref and DerefMut for T

When ShmemBox goes out of scope, the cleanup process of the shared memory is done.

Implementations§

Source§

impl<T> ShmemBox<T>

Source

pub fn own(shmem_box: Self) -> Self

Owns the shared memory. this would result in shared memory cleanup when this pointer goes out of scope.

§Examples
use std::mem;
use shmem_bind::{self as shmem,ShmemError,ShmemBox};

fn main() -> Result<(),ShmemError>{
    // shared memory is created. `shared_mem` owns the shared memory
    let shared_mem = shmem::Builder::new("flink_test_own")
        .with_size(mem::size_of::<i32>() as i64)
        .open()?;
    let mut boxed_val = unsafe { shared_mem.boxed::<i32>() };
     
    // leaking the shared memory to prevent `shared_mem` from cleaning it up.
    ShmemBox::leak(boxed_val);
     
    // shared memory is already present on the machine. `shared_mem` does not own the
    // shared memory.
    let shared_mem = shmem::Builder::new("flink_test_own")
        .with_size(mem::size_of::<i32>() as i64)
        .open()?;
    let boxed_val = unsafe { shared_mem.boxed::<i32>() };

    // own the shared memory to ensure it's cleanup when the shared_mem goes out of scope.
    let boxed_val = ShmemBox::own(boxed_val);

    // boxed_val goes out of scope, the shared memory is cleaned up
    Ok(())
}
Examples found in repository?
examples/message-passing.rs (line 40)
19fn main() -> Result<(), Box<dyn Error>> {
20    // create new shared memory pointer with desired size
21    //
22    // first call to this function with the same FILE_LINK_ID would result in creating a new shared
23    // memory file and owning it. this would result in deleting the shared memory when the variable
24    // goes out of scope.
25    // the second call to this function will only open shared memory and would not delete it.
26    let shared_mem = shmem::Builder::new("shmem-example_message-passing.shm")
27        .with_size(mem::size_of::<Message>() as i64)
28        .open()?;
29
30    // wrap the raw shared memory ptr with desired Boxed type
31    // user must ensure that the data the pointer is pointing to is initialized and valid for use
32    let mut message = unsafe { shared_mem.boxed::<Message>() };
33
34    let mut args = std::env::args();
35    let num_args = args.len();
36    match num_args {
37        // parent process
38        1 => {
39            // ensure that first process owns the shared memory (used for cleanup)
40            let mut message = ShmemBox::own(message);
41
42            // initiate the data behind the boxed pointer
43            message.val = 1;
44
45            let binary_path = args.next().unwrap();
46            let new_val = 5;
47            // create new process to mutate the shared memory
48            let mut handle = Command::new(&binary_path)
49                .arg(format!("{new_val}"))
50                .spawn()
51                .unwrap();
52            handle.wait()?;
53
54            // assert that the new process mutated the shared memory
55            assert_eq!(message.val, new_val);
56
57            // message is dropped here, shared memory IS deallocated
58        }
59        // child process
60        2 => {
61            let value = std::env::args().last().unwrap().parse()?;
62
63            message.val = value;
64
65            // message is dropped here, shared memory IS NOT deallocated
66        }
67        _ => unimplemented!(),
68    }
69    Ok(())
70}
Source

pub fn leak(shmem_box: Self)

Leaks the shared memory and prevents the cleanup if the ShmemBox is the owner of the shared memory. This function is useful when you want to create a shared memory which lasts longer than the process creating it.

§Examples
use std::mem;
use shmem_bind::{self as shmem,ShmemError,ShmemBox};

fn main() -> Result<(),ShmemError>{
    // shared memory is created. `shared_mem` owns the shared memory
    let shared_mem = shmem::Builder::new("flink_test_leak")
        .with_size(mem::size_of::<i32>() as i64)
        .open()?;
    let mut boxed_val = unsafe { shared_mem.boxed::<i32>() };
     
    // leaking the shared memory to prevent `shared_mem` from cleaning it up.
    ShmemBox::leak(boxed_val);
     
    // shared memory is already present on the machine. `shared_mem` does not own the
    // shared memory.
    let shared_mem = shmem::Builder::new("flink_test_leak")
        .with_size(mem::size_of::<i32>() as i64)
        .open()?;
    let boxed_val = unsafe { shared_mem.boxed::<i32>() };

    // own the shared memory to ensure it's cleanup when the shared_mem goes out of scope.
    let boxed_val = ShmemBox::own(boxed_val);

    // boxed_val goes out of scope, the shared memory is cleaned up
    Ok(())
}

Trait Implementations§

Source§

impl<T: Debug> Debug for ShmemBox<T>

Source§

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

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

impl<T> Deref for ShmemBox<T>

Source§

type Target = T

The resulting type after dereferencing.
Source§

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

Dereferences the value.
Source§

impl<T> DerefMut for ShmemBox<T>

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
Source§

impl<T> Drop for ShmemBox<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<T: Send> Send for ShmemBox<T>

Source§

impl<T: Sync> Sync for ShmemBox<T>

§Safety

Shared memory is shared between processes. If it can withstand multiple processes mutating it, it can sure handle a thread or two!

Auto Trait Implementations§

§

impl<T> Freeze for ShmemBox<T>

§

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

§

impl<T> Unpin for ShmemBox<T>

§

impl<T> UnwindSafe for ShmemBox<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<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
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.