zenoh_shm/api/client_storage/
mod.rs1use std::{
16 collections::BTreeMap,
17 sync::{Arc, RwLock},
18};
19
20use static_init::dynamic;
21use zenoh_result::{bail, ZResult};
22
23use crate::{
24 api::{
25 client::{shm_client::ShmClient, shm_segment::ShmSegment},
26 common::{types::ProtocolID, with_id::WithProtocolID},
27 protocol_implementations::posix::posix_shm_client::PosixShmClient,
28 },
29 reader::{ClientStorage, GlobalDataSegmentId},
30};
31
32#[dynamic(lazy, drop)]
33#[zenoh_macros::unstable_doc]
36pub static mut GLOBAL_CLIENT_STORAGE: Arc<ShmClientStorage> = Arc::new(
37 ShmClientStorage::builder()
38 .with_default_client_set()
39 .build(),
40);
41
42#[zenoh_macros::unstable_doc]
44pub struct ShmClientSetBuilder;
45
46impl ShmClientSetBuilder {
47 #[zenoh_macros::unstable_doc]
49 pub fn with_client(self, client: Arc<dyn ShmClient>) -> ShmClientStorageBuilder {
50 let clients = BTreeMap::from([(client.id(), client)]);
51 ShmClientStorageBuilder::new(clients)
52 }
53
54 #[zenoh_macros::unstable_doc]
56 pub fn with_clients(self, clients: &[Arc<dyn ShmClient>]) -> ShmClientStorageBuilder {
57 let clients = clients
58 .iter()
59 .cloned()
60 .map(|client| (client.id(), client))
61 .collect();
62 ShmClientStorageBuilder::new(clients)
63 }
64
65 #[zenoh_macros::unstable_doc]
67 pub fn with_default_client_set(self) -> ShmClientStorageBuilder {
68 let client = PosixShmClient {};
69 let clients = BTreeMap::from([(client.id(), Arc::new(client) as Arc<dyn ShmClient>)]);
70 ShmClientStorageBuilder::new(clients)
71 }
72}
73
74#[zenoh_macros::unstable_doc]
75pub struct ShmClientStorageBuilder {
76 clients: BTreeMap<ProtocolID, Arc<dyn ShmClient>>,
77}
78
79impl ShmClientStorageBuilder {
80 fn new(clients: BTreeMap<ProtocolID, Arc<dyn ShmClient>>) -> Self {
81 Self { clients }
82 }
83
84 #[zenoh_macros::unstable_doc]
86 pub fn with_client(mut self, client: Arc<dyn ShmClient>) -> ZResult<Self> {
87 let id = client.id();
88 match self.clients.entry(id) {
89 std::collections::btree_map::Entry::Occupied(occupied) => {
90 bail!("Client already exists for id {id}: {:?}!", occupied)
91 }
92 std::collections::btree_map::Entry::Vacant(vacant) => {
93 vacant.insert(client as Arc<dyn ShmClient>);
94 Ok(self)
95 }
96 }
97 }
98
99 #[zenoh_macros::unstable_doc]
101 pub fn with_clients(mut self, clients: &[Arc<dyn ShmClient>]) -> Self {
102 self.clients
103 .extend(clients.iter().cloned().map(|client| (client.id(), client)));
104 self
105 }
106
107 #[zenoh_macros::unstable_doc]
109 pub fn build(self) -> ShmClientStorage {
110 ShmClientStorage::new(self.clients)
111 }
112}
113
114#[zenoh_macros::unstable_doc]
118#[derive(Debug)]
119pub struct ShmClientStorage {
120 pub(crate) clients: ClientStorage<Arc<dyn ShmClient>>,
121 pub(crate) segments: RwLock<BTreeMap<GlobalDataSegmentId, Arc<dyn ShmSegment>>>,
122}
123
124impl Eq for ShmClientStorage {}
125
126impl PartialEq for ShmClientStorage {
127 fn eq(&self, other: &Self) -> bool {
128 std::ptr::eq(self, other)
129 }
130}
131
132impl ShmClientStorage {
133 #[zenoh_macros::unstable_doc]
135 pub fn builder() -> ShmClientSetBuilder {
136 ShmClientSetBuilder
137 }
138
139 #[zenoh_macros::unstable_doc]
141 pub fn supported_protocols(&self) -> Vec<ProtocolID> {
142 self.clients.get_clients().keys().copied().collect()
143 }
144
145 fn new(clients: BTreeMap<ProtocolID, Arc<dyn ShmClient>>) -> Self {
146 Self {
147 clients: ClientStorage::new(clients),
148 segments: RwLock::default(),
149 }
150 }
151}