message_passing/
message-passing.rs

1extern crate shmem_bind;
2use shmem_bind::{self as shmem, ShmemBox};
3
4use std::error::Error;
5use std::mem;
6use std::process::Command;
7
8#[derive(Debug)]
9struct Message {
10    val: i32,
11}
12
13impl Drop for Message {
14    fn drop(&mut self) {
15        println!("message is dropping");
16    }
17}
18
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}