VLink  2.0.0
A high-performance communication middleware
shm_conf.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2026 by Thun Lu. All rights reserved.
3  * Author: Thun Lu <thun.lu@zohomail.cn>
4  * Repo: https://github.com/thun-res/vlink
5  * _ __ __ _ __
6  * | | / / / / (_) ____ / /__
7  * | | / / / / / / / __ \ / //_/
8  * | |/ / / /___ / / / / / / / ,<
9  * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 
24 /**
25  * @file shm_conf.h
26  * @brief Transport configuration for the @c shm:// Iceoryx shared-memory transport.
27  *
28  * @details
29  * @c ShmConf binds the @c shm:// URL scheme to the Eclipse Iceoryx zero-copy
30  * shared-memory transport. Publishers @c loan() a memory chunk directly from the
31  * RouDi-managed memory pool, fill it in place, and @c publish() it; subscribers
32  * receive the chunk by pointer and release it back to the pool when finished. No
33  * payload bytes are ever copied between processes, which makes this the
34  * lowest-latency option for large messages on a single host.
35  *
36  * @par Shared-Memory Layout
37  * @code
38  * RouDi (daemon)
39  * +-----------------------------------------------+
40  * | Mempool: fixed-size chunk segments |
41  * | +------+ +------+ +------+ +------+ +------+ |
42  * | | chk0 | | chk1 | | chk2 | | chk3 | | ... | |
43  * | +------+ +------+ +------+ +------+ +------+ |
44  * +--------^--------------------------^-----------+
45  * | loan() | release()
46  * | |
47  * Publisher process Subscriber process
48  * @endcode
49  *
50  * @par Loan / Release Flow
51  * @code
52  * Publisher: chunk = loan(size); fill(chunk); publish(chunk);
53  * \
54  * \--> queue (per topic in RouDi)
55  * \
56  * Subscriber: chunk = take(); \--> chunk arrival
57  * consume(chunk); release(chunk);
58  * @endcode
59  *
60  * @par Supported Node Types
61  *
62  * | Publisher | Subscriber | Server | Client | Getter | Setter |
63  * | :-------: | :--------: | :----: | :----: | :----: | :----: |
64  * | yes | yes | yes | yes | yes | yes |
65  *
66  * @par URL Format
67  * @code
68  * shm://<address>[?event=<name>&domain=<N>&depth=<N>&history=<N>&wait=<ms>]
69  * @endcode
70  *
71  * | Component | Description |
72  * | ---------- | ---------------------------------------------------------------------- |
73  * | @c address | Iceoryx service/topic name (URL host concatenated with path) |
74  * | @c event | Optional secondary event name (@c ?event=) |
75  * | @c domain | Iceoryx domain ID (@c ?domain=); defaults to @c 0 |
76  * | @c depth | Queue capacity override; @c 0 uses the Iceoryx default |
77  * | @c history | History count (@c ?history=); @c 0 from URL, or @c 1 for field nodes |
78  * | @c wait | Blocking-wait timeout in ms for pub/sub; not valid for RPC or fields |
79  *
80  * @par RouDi Lifecycle
81  * RouDi is the Iceoryx memory-manager daemon. It can either be started externally
82  * (preferred for production) or hosted in-process for tests and single-process tools.
83  * @code
84  * // Option A: embedded RouDi (single-process tools):
85  * vlink::ShmConf::init_roudi();
86  *
87  * // Option B: connect this process to an external RouDi daemon:
88  * vlink::ShmConf::init_runtime("my_app");
89  *
90  * // Option C: one-line preflight that picks whichever is needed:
91  * vlink::ShmConf::auto_init_roudi();
92  *
93  * // ... create shm:// nodes ...
94  *
95  * vlink::ShmConf::deinit_runtime();
96  * @endcode
97  *
98  * @note Compiled only when @c VLINK_SUPPORT_SHM is defined.
99  * @note Iceoryx caps @c address and @c event at 80 characters each.
100  * @note @c wait mode is only valid for @c kPublisher / @c kSubscriber; using it
101  * with RPC or field nodes causes @c parse_protocol() to return @c false.
102  */
103 
104 #pragma once
105 
106 #ifdef VLINK_SUPPORT_SHM
107 
108 #include <cstdint>
109 #include <string>
110 
111 #include "../impl/conf.h"
112 
113 namespace vlink {
114 
115 /**
116  * @struct ShmConf
117  * @brief Concrete @c Conf describing an Iceoryx shared-memory endpoint addressed by a @c shm:// URL.
118  *
119  * @details
120  * Captures the service/topic address, optional event filter, Iceoryx domain ID,
121  * queue capacity override, history count, and blocking-wait timeout. Both
122  * @c address and @c event are limited to 80 characters by Iceoryx naming
123  * constraints.
124  */
125 struct VLINK_EXPORT ShmConf final : public Conf {
126  std::string address; ///< Iceoryx service/topic address (URL host plus path); maximum 80 characters.
127  std::string event; ///< Optional secondary event name; maximum 80 characters.
128  int32_t domain{0}; ///< Iceoryx domain identifier (non-negative).
129  int32_t depth{0}; ///< Queue capacity override; @c 0 keeps the Iceoryx default.
130  int32_t history{0}; ///< History count; URL parsing defaults to @c 0, or @c 1 for setter / getter nodes.
131  int32_t wait{0}; ///< Blocking-wait timeout in milliseconds; positive values enable pub/sub wait mode.
132 
133  /**
134  * @brief Builds a @c ShmConf from its six logical fields.
135  *
136  * @param _address Service/topic address string; maximum 80 characters.
137  * @param _event Optional event name; maximum 80 characters; empty by default.
138  * @param _domain Iceoryx domain identifier; defaults to @c 0.
139  * @param _depth Queue capacity override; defaults to @c 0.
140  * @param _history History count; defaults to @c 0.
141  * @param _wait Blocking-wait timeout in milliseconds; defaults to @c 0 (disabled).
142  */
143  explicit ShmConf(const std::string& _address, const std::string& _event = "", int32_t _domain = 0, int32_t _depth = 0,
144  int32_t _history = 0, int32_t _wait = 0);
145 
146  /**
147  * @brief Component-wise equality on all configuration fields.
148  *
149  * @param conf Configuration to compare with.
150  * @return @c true when every field of @c *this matches @p conf.
151  */
152  [[nodiscard]] bool operator==(const ShmConf& conf) const noexcept;
153 
154  /**
155  * @brief Logical negation of @c operator==.
156  *
157  * @param conf Configuration to compare with.
158  * @return @c true when any field differs from @p conf.
159  */
160  [[nodiscard]] bool operator!=(const ShmConf& conf) const noexcept;
161 
162  /**
163  * @brief Reports this object's transport tag.
164  *
165  * @return @c TransportType::kShm.
166  */
167  [[nodiscard]] TransportType get_transport_type() const override;
168 
169  /**
170  * @brief Reports whether an in-process RouDi was started in this process.
171  *
172  * @details
173  * Delegates to @c ShmFactory::has_roudi_inited(); meaningful only after a call
174  * to @c init_roudi() inside the same process.
175  *
176  * @return @c true when an embedded RouDi instance is running here.
177  */
178  [[nodiscard]] static bool has_roudi_inited();
179 
180  /**
181  * @brief Reports whether the Iceoryx runtime has been initialised for this process.
182  *
183  * @details
184  * Delegates to @c ShmFactory::has_runtime_inited(); returns @c true after a
185  * successful @c init_runtime() call or after @c global_init() automatically
186  * initialises the runtime.
187  *
188  * @return @c true when the Iceoryx runtime is ready to create endpoints.
189  */
190  [[nodiscard]] static bool has_runtime_inited();
191 
192  /**
193  * @brief Cheap, non-invasive probe for a reachable Iceoryx RouDi daemon.
194  *
195  * @details
196  * Intended for CLI diagnostics, bench preflight, and pre-launch hints. Does
197  * not create an Iceoryx runtime, does not open any port, does not mutate any
198  * global state, and is safe to call repeatedly from any thread.
199  *
200  * @return @c true when RouDi (or a process embedding RouDi such as
201  * @c vlink-proxy) is running on the local host, otherwise @c false.
202  *
203  * @see ShmFactory::has_roudi_running()
204  */
205  [[nodiscard]] static bool has_roudi_running();
206 
207  /**
208  * @brief One-line preflight that guarantees a RouDi is available for @c shm:// nodes.
209  *
210  * @details
211  * On POSIX, an in-process RouDi is started automatically when none is detected.
212  * On Windows, when no external RouDi is detected, returns @c false only if
213  * @p same_process_from_roudi is @c true; otherwise the runtime is initialised
214  * without starting RouDi. Cached across calls.
215  *
216  * @note Calls @c init_runtime() during preflight and tears it down when the
217  * cached manager is destroyed.
218  *
219  * @param same_process_from_roudi @c true when RouDi runs in this same process
220  * (see @c init_roudi()).
221  * @return @c true when RouDi is ready for use, @c false otherwise.
222  *
223  * @see ShmFactory::auto_init_roudi()
224  */
225  [[nodiscard]] static bool auto_init_roudi(bool same_process_from_roudi = false);
226 
227  /**
228  * @brief Starts an embedded Iceoryx RouDi daemon inside the current process.
229  *
230  * @details
231  * Use this when no external RouDi process is running and a single process must
232  * act as both the memory manager and a participant. Must be invoked before any
233  * @c shm:// endpoint is created.
234  *
235  * @param config_path Path to a RouDi XML configuration file; empty selects defaults.
236  * @param memory_strategy Memory pooling strategy; @c 0 selects the default strategy.
237  * @param monitoring_enable @c true to enable process-monitoring inside RouDi.
238  */
239  static void init_roudi(const std::string& config_path = "", int memory_strategy = 0, bool monitoring_enable = true);
240 
241  /**
242  * @brief Registers this process with the Iceoryx RouDi daemon.
243  *
244  * @details
245  * Must be called once before any @c shm:// endpoint is created when connecting
246  * to an external RouDi. The @p name should be unique across all processes
247  * connecting to the same RouDi instance; Iceoryx truncates it to the runtime
248  * name capacity.
249  *
250  * @param name Process registration name; empty selects a generated name.
251  * @param same_process_from_roudi @c true when RouDi runs in this same process
252  * (see @c init_roudi()).
253  */
254  static void init_runtime(const std::string& name = "", bool same_process_from_roudi = false);
255 
256  /**
257  * @brief Unregisters this process from the Iceoryx RouDi daemon.
258  *
259  * @details
260  * Releases all Iceoryx resources associated with the current process. Must be
261  * called before process exit when @c init_runtime() has been used.
262  */
263  static void deinit_runtime();
264 
265 #ifndef VLINK_ENABLE_C_INTERFACE
267 #endif
269  VLINK_CONF_IMPL(ShmConf)
270 };
271 
272 ////////////////////////////////////////////////////////////////
273 /// Details
274 ////////////////////////////////////////////////////////////////
275 
276 inline ShmConf::ShmConf(const std::string& _address, const std::string& _event, int32_t _domain, int32_t _depth,
277  int32_t _history, int32_t _wait)
278  : address(_address), event(_event), domain(_domain), depth(_depth), history(_history), wait(_wait) {}
279 
280 inline bool ShmConf::operator==(const ShmConf& conf) const noexcept {
281  return address == conf.address && event == conf.event && domain == conf.domain && depth == conf.depth &&
282  history == conf.history && wait == conf.wait;
283 }
284 
285 inline bool ShmConf::operator!=(const ShmConf& conf) const noexcept { return !(*this == conf); }
286 
287 inline TransportType ShmConf::get_transport_type() const { return TransportType::kShm; }
288 
289 } // namespace vlink
290 
291 #endif
#define VLINK_CONF_IMPL(classname)
Convenience macro that emits the standard concrete conf boilerplate.
Definition: conf.h:251
#define VLINK_DECLARE_GLOBAL_PROPERTY()
Declares per-transport static configuration storage and access helpers.
Definition: conf.h:309
#define VLINK_ALLOW_IMPL_TYPE(type)
Records the bitmask of ImplType values supported by a conf.
Definition: conf.h:292
#define VLINK_EXPORT
Definition: macros.h:81