zenoh_shm/posix_shm/
struct_in_shm.rs

1//
2// Copyright (c) 2025 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12//   ZettaScale Zenoh Team, <zenoh@zettascale.tech>
13//
14
15use std::{
16    marker::PhantomData,
17    mem::size_of,
18    num::NonZeroUsize,
19    ops::{Deref, DerefMut},
20};
21
22// use stabby::IStable;
23use zenoh_result::ZResult;
24
25use super::segment::Segment;
26use crate::shm;
27
28/// An SHM segment that contains data structure
29#[derive(Debug)]
30pub struct StructInSHM<ID, Elem>
31where
32    rand::distributions::Standard: rand::distributions::Distribution<ID>,
33    ID: shm::SegmentID,
34{
35    inner: Segment<ID>,
36    _phantom: PhantomData<Elem>,
37}
38
39unsafe impl<ID, Elem: Sync> Sync for StructInSHM<ID, Elem>
40where
41    rand::distributions::Standard: rand::distributions::Distribution<ID>,
42    ID: shm::SegmentID,
43{
44}
45unsafe impl<ID, Elem: Send> Send for StructInSHM<ID, Elem>
46where
47    rand::distributions::Standard: rand::distributions::Distribution<ID>,
48    ID: shm::SegmentID,
49{
50}
51
52impl<ID, Elem> StructInSHM<ID, Elem>
53where
54    rand::distributions::Standard: rand::distributions::Distribution<ID>,
55    // Elem: IStable<ContainsIndirections = stabby::abi::B0>, // TODO: stabby does not support IStable for big arrays
56    ID: shm::SegmentID,
57{
58    // Perform compile time check that Elem is not a ZST
59    const _S: () = if size_of::<Elem>() == 0 {
60        panic!("Elem is a ZST. ZSTs are not allowed");
61    };
62
63    pub fn create() -> ZResult<Self> {
64        let alloc_size = NonZeroUsize::try_from(size_of::<Elem>())?;
65        let inner = Segment::create(alloc_size)?;
66        Ok(Self {
67            inner,
68            _phantom: PhantomData,
69        })
70    }
71
72    pub fn open(id: ID) -> ZResult<Self> {
73        let inner = Segment::open(id)?;
74        Ok(Self {
75            inner,
76            _phantom: PhantomData,
77        })
78    }
79
80    pub fn id(&self) -> ID {
81        self.inner.id()
82    }
83
84    /// Retrieves mut element
85    pub fn elem_mut(&self) -> *mut Elem {
86        self.inner.as_ptr() as *mut Elem
87    }
88}
89
90impl<ID, Elem> Deref for StructInSHM<ID, Elem>
91where
92    rand::distributions::Standard: rand::distributions::Distribution<ID>,
93    // Elem: IStable<ContainsIndirections = stabby::abi::B0>, // TODO: stabby does not support IStable for big arrays
94    ID: shm::SegmentID,
95{
96    type Target = Elem;
97
98    fn deref(&self) -> &Self::Target {
99        unsafe { &*(self.inner.as_ptr() as *const Elem) }
100    }
101}
102
103impl<ID, Elem> DerefMut for StructInSHM<ID, Elem>
104where
105    rand::distributions::Standard: rand::distributions::Distribution<ID>,
106    // Elem: IStable<ContainsIndirections = stabby::abi::B0>, // TODO: stabby does not support IStable for big arrays
107    ID: shm::SegmentID,
108{
109    fn deref_mut(&mut self) -> &mut Self::Target {
110        unsafe { &mut *(self.inner.as_ptr() as *mut Elem) }
111    }
112}