shared_memory 0.12.4

A user friendly crate that allows you to share memory between processes
Documentation
use shared_memory::ShmemConf;
use std::sync::mpsc::channel;
use std::thread;

#[test]
fn persistence() {
    let os_id = {
        let mut shmem = ShmemConf::new().size(4096).create().unwrap();
        shmem.set_owner(false);
        String::from(shmem.get_os_id())
    };
    let mut shmem = ShmemConf::new().os_id(os_id).open().unwrap();
    shmem.set_owner(true);
}

#[test]
fn posix_behavior() {
    let (tx_a, rx_a) = channel();
    let (tx_b, rx_b) = channel();
    let (tx_c, rx_c) = channel();

    let thread_a = thread::Builder::new()
        .name(String::from("A"))
        .spawn(move || {
            let os_id = {
                let shmem = ShmemConf::new().size(4096).create().unwrap();
                let os_id = String::from(shmem.get_os_id());
                // Creating two `Shmem`s with the same `os_id` should fail
                assert!(ShmemConf::new().size(4096).os_id(&os_id).create().is_err());
                tx_b.send(os_id.clone()).unwrap();
                tx_c.send(os_id.clone()).unwrap();
                // Wait for threads B and C to confirm they have created their instances.
                rx_a.recv().unwrap();
                rx_a.recv().unwrap();
                // Tell thread B to drop its instance.
                tx_b.send(String::new()).unwrap();
                os_id
                // Owned shmem drops here after a second owned instance has been
                // dropped in thread B.
            };
            // Should not be able to reopen shared memory after an owned instance
            // has been dropped in thread B.
            assert!(ShmemConf::new().size(4096).os_id(os_id).open().is_err());
            // Tell thread C to drop the unowned instance.
            tx_c.send(String::new()).unwrap();
        })
        .unwrap();
    let thread_b = thread::Builder::new()
        .name(String::from("B"))
        .spawn({
            let tx_a = tx_a.clone();
            move || {
                let existing_os_id = rx_b.recv().unwrap();
                // Creating two `Shmem`s with the same `os_id` should fail
                assert!(ShmemConf::new()
                    .size(4096)
                    .os_id(&existing_os_id)
                    .create()
                    .is_err());
                {
                    // Should be able to open the existing shared memory
                    let mut shmem = ShmemConf::new().os_id(&existing_os_id).open().unwrap();
                    shmem.set_owner(true);
                    tx_a.send(String::new()).unwrap();
                    rx_b.recv().unwrap();
                    // When the owning shmem is dropped here, we
                    // 1. should be able to still drop the original shared memory in thread A.
                    // 2. should not be able to reopen it with the same name in thread A, even
                    // if an instance is kept alive in thread C.
                }
            }
        })
        .unwrap();
    let thread_c = thread::Builder::new()
        .name(String::from("C"))
        .spawn(move || {
            // This thread keeps a shared memory instance alive until it's told to
            // drop it.
            let existing_os_id = rx_c.recv().unwrap();
            let _shmem = ShmemConf::new().os_id(&existing_os_id).open().unwrap();
            // Indicate to thread A that the instance has been created.
            tx_a.send(String::new()).unwrap();
            // Shut down signal.
            rx_c.recv().unwrap();
        })
        .unwrap();
    thread_a.join().unwrap();
    thread_b.join().unwrap();
    thread_c.join().unwrap();
}