Flow-IPC 1.0.2
Flow-IPC project: Full implementation reference.
blob_transport.hpp
Go to the documentation of this file.
1/* Flow-IPC: Core
2 * Copyright 2023 Akamai Technologies, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the
5 * "License"); you may not use this file except in
6 * compliance with the License. You may obtain a copy
7 * of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in
12 * writing, software distributed under the License is
13 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
14 * CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing
16 * permissions and limitations under the License. */
17
18/// @file
19
20// Not compiled: for documentation only. Contains concept docs as of this writing.
21#ifndef IPC_DOXYGEN_ONLY
22static_assert(false, "As of this writing this is a documentation-only \"header\" "
23 "(the \"source\" is for humans and Doxygen only).");
24#else // ifdef IPC_DOXYGEN_ONLY
25
26namespace ipc::transport
27{
28
29// Types.
30
31/**
32 * A documentation-only *concept* defining the behavior of an object capable of reliably/in-order *sending* of
33 * discrete messages, each containing a binary blob. This is paired with
34 * the Blob_receiver concept which defines reception of such messages.
35 *
36 * The concept is exactly identical to Native_handle_sender except that in the latter each message consists
37 * of 0-1 native handles and 0-1 binary blobs; whereas here it is always exactly 1 of the latter. More precisely,
38 * each message contains 1 binary blob, whose length must be at least 1 byte. You may interpret notes in common-sense
39 * fashion; for example send_blob_max_size() here corresponds to `send_meta_blob_max_size()` there.
40 *
41 * Therefore we keep the documentation very light, only pointing out the differences against Native_handle_sender --
42 * which are summarized in the preceding paragraph. All other notes from Native_handle_sender apply here.
43 *
44 * @see Native_handle_sender, an identical concept with 1 feature (native handle transmission) added.
45 */
47{
48public:
49 // Constants.
50
51 /// Shared_name relative-folder fragment (no separators) identifying this resource type. Equals `_receiver`'s.
53
54 // Constructors/destructor.
55
56 /**
57 * Default ctor: Creates a peer object in NULL (neither connected nor connecting) state.
58 *
59 * All notes from Native_handle_sender() default ctor doc header apply.
60 */
62
63 /**
64 * `sync_io`-core-adopting ctor: Creates a peer object in PEER state by subsuming a `sync_io` core in that state.
65 *
66 * @param sync_io_core_in_peer_state_moved
67 * See Native_handle_sender concept.
68 */
69 Blob_sender(sync_io::Blob_sender&& sync_io_core_in_peer_state_moved);
70
71 /**
72 * Move-constructs from `src`; `src` becomes as-if default-cted (therefore in NULL state).
73 *
74 * @param src
75 * Source object. For reasonable uses of `src` after this ctor returns: see default ctor doc header.
76 */
78
79 /// Disallow copying.
80 Blob_sender(const Blob_sender&) = delete;
81
82 /**
83 * Destroys this peer endpoint which will end the conceptual outgoing-direction pipe (in PEER state, and if it
84 * is still active) and cancels any pending completion handlers by invoking them ASAP with
85 * error::Code::S_OBJECT_SHUTDOWN_ABORTED_COMPLETION_HANDLER.
86 *
87 * All notes from ~Native_handle_sender() doc header apply.
88 */
90
91 // Methods.
92
93 /**
94 * Move-assigns from `src`; `*this` acts as if destructed; `src` becomes as-if default-cted (therefore in NULL state).
95 * No-op if `&src == this`.
96 *
97 * @see ~Blob_sender().
98 *
99 * @param src
100 * Source object. For reasonable uses of `src` after this ctor returns: see default ctor doc header.
101 * @return `*this`.
102 */
104 // Methods.
105
106 /// Disallow copying.
108
109 /**
110 * In PEER state: Returns max `blob.size()` such that send_blob() shall not fail due to too-long
111 * payload with error::Code::S_INVALID_ARGUMENT. Always the same value once in PEER state. The opposing
112 * Native_handle_receiver::receive_blob_max_size()` shall return the same value (in the opposing object potentially
113 * in a different process).
114 *
115 * If `*this` is not in PEER state (in particular if it is default-cted or moved-from), returns zero; else
116 * a positive value.
117 *
118 * @return See above.
119 */
120 size_t send_blob_max_size() const;
121
122 /**
123 * In PEER state: Synchronously, non-blockingly sends one discrete message, reliably and in-order, to the opposing
124 * peer; the message consists of the provided binary blob (of length at least 1 byte). Providing a null blob
125 * results in undefined behavior (assertion may trip).
126 *
127 * All notes from Native_handle_sender::send_native_handle() doc header apply.
128 *
129 * @param blob
130 * A binary blob to send; behavior undefined unless `blob.size() >= 1`.
131 * @param err_code
132 * See above.
133 * @return See above.
134 */
135 bool send_blob(const util::Blob_const& blob, Error_code* err_code = 0);
136
137 /**
138 * Equivalent to send_blob() but sends a graceful-close message instead of the usual payload; the opposing
139 * peer's Blob_receiver shall receive it reliably and in-order via Blob_receiver::async_receive_blob() in the form of
140 * #Error_code = error::Code::S_RECEIVES_FINISHED_CANNOT_RECEIVE.
141 *
142 * All notes from Native_handle_sender::async_end_sending() doc header apply.
143 *
144 * @tparam Task_err
145 * See above.
146 * @param on_done_func
147 * See above.
148 * @return See above.
149 */
150 template<typename Task_err>
151 bool async_end_sending(Task_err&& on_done_func);
152
153 /**
154 * Equivalent to `async_end_sending(F)` wherein `F()` does nothing.
155 *
156 * All notes from Native_handle_sender::end_sending() doc header apply.
157 *
158 * @return See above.
159 */
161
162 /**
163 * In PEER state: Irreversibly enables periodic auto-pinging of opposing receiver with low-level messages that
164 * are ignored except that they reset any idle timer as enabled via Blob_receiver::idle_timer_run()
165 * (or similar).
166 *
167 * All notes from Native_handle_receiver::auto_ping() doc header apply.
168 *
169 * @param period
170 * See above.
171 * @return See above.
172 */
173 bool auto_ping();
174}; // class Blob_sender
175
176/**
177 * A documentation-only *concept* defining the behavior of an object capable of reliably/in-order *receiving* of
178 * discrete messages, each containing a binary blob. This is paired with
179 * the Blob_sender concept which defines sending of such messages.
180 *
181 * The concept is exactly identical to Native_handle_receiver except that in the latter each message consists
182 * of 0-1 native handles and 0-1 binary blobs; whereas here it is always exactly 1 of the latter. More precisely,
183 * each message contains 1 binary blob, whose length must be at least 1 byte. You may interpret notes in common-sense
184 * fashion; for example receive_blob_max_size() here corresponds to `receive_meta_blob_max_size()` there.
185 *
186 * Therefore we keep the documentation very light, only pointing out the differences against Native_handle_receiver --
187 * which are summarized in the preceding paragraph. All other notes from Native_handle_receiver apply here.
188 *
189 * @see Native_handle_receiver, an identical concept with 1 feature (native handle transmission) added.
190 */
192{
193public:
194 // Constants.
195
196 /// Shared_name relative-folder fragment (no separators) identifying this resource type. Equals `_sender`'s.
198
199 /**
200 * If `false` then `blob.size() > receive_blob_max_size()` in PEER-state async_receive_blob()
201 * shall yield non-pipe-hosing error::Code::INVALID_ARGUMENT, and it shall never yield
202 * pipe-hosing error::Code::S_MESSAGE_SIZE_EXCEEDS_USER_STORAGE; else the latter may occur, while the former
203 * shall never occur for that reason.
204 *
205 * @see "Blob underflow semantics" in Native_handle_sender concept doc header; they apply equally here.
206 */
207 static constexpr bool S_BLOB_UNDERFLOW_ALLOWED = value;
208
209 // Constructors/destructor.
210
211 /**
212 * Default ctor: Creates a peer object in NULL (neither connected nor connecting) state.
213 *
214 * All notes from Native_handle_receiver() default ctor doc header apply.
215 */
217
218 /**
219 * `sync_io`-core-adopting ctor: Creates a peer object in PEER state by subsuming a `sync_io` core in that state.
220 *
221 * @param sync_io_core_in_peer_state_moved
222 * See Native_handle_sender concept.
223 */
224 Blob_receiver(sync_io::Blob_receiver&& sync_io_core_in_peer_state_moved);
225
226 /**
227 * Move-constructs from `src`; `src` becomes as-if default-cted (therefore in NULL state).
228 *
229 * @param src
230 * Source object. For reasonable uses of `src` after this ctor returns: see default ctor doc header.
231 */
233
234 /// Disallow copying.
235 Blob_receiver(const Blob_receiver&) = delete;
236
237 /**
238 * Destroys this peer endpoint which will end the conceptual incoming-direction pipe (in PEER state, and if it
239 * is still active) and cancels any pending completion handlers by invoking them ASAP with
240 * error::Code::S_OBJECT_SHUTDOWN_ABORTED_COMPLETION_HANDLER.
241 *
242 * All notes from ~Native_handle_receiver() doc header apply.
243 */
245
246 // Methods.
247
248 /**
249 * Move-assigns from `src`; `*this` acts as if destructed; `src` becomes as-if default-cted (therefore in NULL state).
250 * No-op if `&src == this`.
251 *
252 * @see ~Blob_receiver().
253 *
254 * @param src
255 * Source object. For reasonable uses of `src` after this ctor returns: see default ctor doc header.
256 * @return `*this`.
257 */
259
260 /// Disallow copying.
262
263 /**
264 * In PEER state: Returns min `target_blob.size()` such that (1) async_receive_blob() shall not fail
265 * with error::Code::S_INVALID_ARGUMENT (only if #S_BLOB_UNDERFLOW_ALLOWED is `false`; otherwise not relevant),
266 * and (2) it shall *never* fail with error::Code::S_MESSAGE_SIZE_EXCEEDS_USER_STORAGE. Please see
267 * "Blob underflow semantics" (for Native_handle_receiver, but applied in common-sense fashion to us) for
268 * explanation of these semantics.
269 *
270 * Always the same value once in PEER state. The opposing
271 * Native_handle_sender::send_blob_max_size() shall return the same value (in the opposing object potentially
272 * in a different process).
273 *
274 * If `*this` is not in PEER state (in particular if it is default-cted or moved-from), returns zero; else
275 * a positive value.
276 *
277 * @return See above.
278 */
279 size_t receive_blob_max_size() const;
280
281 /**
282 * In PEER state: Asynchronously awaits one discrete message -- as sent by the opposing peer via
283 * Blob_sender::send_blob() or `"Blob_sender::*end_sending()"` -- and
284 * receives it into the given target locations, reliably and in-order.
285 *
286 * All notes from Native_handle_receiver::async_receive_native_handle() doc header apply. In particular
287 * watch out for the semantics regarding `target_blob.size()` and potential resulting errors.
288 *
289 * @tparam Task_err_sz
290 * See above.
291 * @param target_blob
292 * `target_blob.data()...` shall be written to by the time `on_done_func()` is executed with a falsy
293 * code, bytes numbering `N`, where `N` is passed to that callback. `N` shall not exceed
294 * `target_blob.size()`. See above.
295 * @param on_done_func
296 * See above.
297 * @return See above.
298 */
299 template<typename Task_err_sz>
300 bool async_receive_blob(const util::Blob_mutable& target_blob,
301 Task_err_sz&& on_done_func);
302
303 /**
304 * In PEER state: Irreversibly enables a conceptual idle timer whose potential side effect is, once at least
305 * the specified time has passed since the last received low-level traffic (or this call, whichever most
306 * recently occurred), to emit the pipe-hosing error error::Code::S_RECEIVER_IDLE_TIMEOUT.
307 *
308 * All notes from Native_handle_receiver::idle_timer_run() doc header apply.
309 *
310 * @param timeout
311 * See above.
312 * @return See above.
313 */
315}; // class Blob_receiver
316
317} // namespace ipc::transport
A documentation-only concept defining the behavior of an object capable of reliably/in-order receivin...
Blob_receiver()
Default ctor: Creates a peer object in NULL (neither connected nor connecting) state.
Blob_receiver(const Blob_receiver &)=delete
Disallow copying.
size_t receive_blob_max_size() const
In PEER state: Returns min target_blob.size() such that (1) async_receive_blob() shall not fail with ...
Blob_receiver & operator=(const Blob_receiver &)=delete
Disallow copying.
bool idle_timer_run(util::Fine_duration timeout)
In PEER state: Irreversibly enables a conceptual idle timer whose potential side effect is,...
Blob_receiver & operator=(Blob_receiver &&src)
Move-assigns from src; *this acts as if destructed; src becomes as-if default-cted (therefore in NULL...
Blob_receiver(sync_io::Blob_receiver &&sync_io_core_in_peer_state_moved)
sync_io-core-adopting ctor: Creates a peer object in PEER state by subsuming a sync_io core in that s...
static const Shared_name S_RESOURCE_TYPE_ID
Shared_name relative-folder fragment (no separators) identifying this resource type....
bool async_receive_blob(const util::Blob_mutable &target_blob, Task_err_sz &&on_done_func)
In PEER state: Asynchronously awaits one discrete message – as sent by the opposing peer via Blob_sen...
Blob_receiver(Blob_receiver &&src)
Move-constructs from src; src becomes as-if default-cted (therefore in NULL state).
static constexpr bool S_BLOB_UNDERFLOW_ALLOWED
If false then blob.size() > receive_blob_max_size() in PEER-state async_receive_blob() shall yield no...
~Blob_receiver()
Destroys this peer endpoint which will end the conceptual incoming-direction pipe (in PEER state,...
A documentation-only concept defining the behavior of an object capable of reliably/in-order sending ...
Blob_sender()
Default ctor: Creates a peer object in NULL (neither connected nor connecting) state.
bool end_sending()
Equivalent to async_end_sending(F) wherein F() does nothing.
Blob_sender(sync_io::Blob_sender &&sync_io_core_in_peer_state_moved)
sync_io-core-adopting ctor: Creates a peer object in PEER state by subsuming a sync_io core in that s...
bool async_end_sending(Task_err &&on_done_func)
Equivalent to send_blob() but sends a graceful-close message instead of the usual payload; the opposi...
Blob_sender(Blob_sender &&src)
Move-constructs from src; src becomes as-if default-cted (therefore in NULL state).
Blob_sender & operator=(const Blob_sender &)=delete
Disallow copying.
bool send_blob(const util::Blob_const &blob, Error_code *err_code=0)
In PEER state: Synchronously, non-blockingly sends one discrete message, reliably and in-order,...
~Blob_sender()
Destroys this peer endpoint which will end the conceptual outgoing-direction pipe (in PEER state,...
Blob_sender & operator=(Blob_sender &&src)
Move-assigns from src; *this acts as if destructed; src becomes as-if default-cted (therefore in NULL...
bool auto_ping()
In PEER state: Irreversibly enables periodic auto-pinging of opposing receiver with low-level message...
static const Shared_name S_RESOURCE_TYPE_ID
Shared_name relative-folder fragment (no separators) identifying this resource type....
size_t send_blob_max_size() const
In PEER state: Returns max blob.size() such that send_blob() shall not fail due to too-long payload w...
Blob_sender(const Blob_sender &)=delete
Disallow copying.
A documentation-only concept: what transport::Blob_receiver is to transport::Native_handle_receiver (...
A documentation-only concept: what transport::Blob_sender is to transport::Native_handle_sender (name...
String-wrapping abstraction representing a name uniquely distinguishing a kernel-persistent entity fr...
Flow-IPC module providing transmission of structured messages and/or low-level blobs (and more) betwe...
boost::asio::mutable_buffer Blob_mutable
Short-hand for an mutable blob somewhere in memory, stored as exactly a void* and a size_t.
Definition: util_fwd.hpp:140
flow::Fine_duration Fine_duration
Short-hand for Flow's Fine_duration.
Definition: util_fwd.hpp:117
boost::asio::const_buffer Blob_const
Short-hand for an immutable blob somewhere in memory, stored as exactly a void const * and a size_t.
Definition: util_fwd.hpp:134
flow::Error_code Error_code
Short-hand for flow::Error_code which is very common.
Definition: common.hpp:298