Flow-IPC 3.0.0
Flow-IPC project: Full implementation reference.
struc_fwd.hpp
Go to the documentation of this file.
1/* Flow-IPC: Structured Transport
2 * Copyright (c) 2023 Akamai Technologies, Inc.; and other contributors.
3 * Each commit is copyright by its respective author or author's employer.
4 *
5 * Licensed under the MIT License:
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE. */
24
25/// @file
26#pragma once
27
29#include "ipc/transport/struc/schema/detail/structured_msg.capnp.h"
30#include "ipc/common.hpp"
31
33{
34
35// Types.
36
37template<typename Base_t>
38struct Msg_out_impl;
39template<typename Base_t>
40struct Msg_in_impl;
41
42// Free functions.
43
44/**
45 * Given user- or internal-message-describing metadata values as arguments, loads (via the provided
46 * `capnp::MessageBuilder`) a `schema::detail::StructuredMessage` capnp-`struct` so as to contain those values.
47 * The resulting `MessageBuilder` a/k/a #Capnp_msg_builder_interface can then be serialized as an mdt header
48 * for an out-message.
49 *
50 * The out-arg `*builder` may be reused for performance; meaning if it encoded mdt for out-message X earlier,
51 * it can be reused to encode mdt for out-message Y now with higher perf than if a fresh `*builder` had to be
52 * created. There are however the following limitations.
53 * - If you're loading mdt for an *internal* message (hence `internal_msg_builder_or_null != nullptr`, and
54 * `id_or_none == 0`), then `*builder` must be fresh. Else behavior is undefined.
55 * - Else (it's a user message), and indeed `*builder` is previously-`load_mdt()`ed:
56 * - `*builder` must have been used to also load a user message's MDT. Else behavior is undefined.
57 * - Typically reuse is possible. If so load_mdt() shall return `true` indicating success.
58 * - In some rare cases it is not possible. If so load_mdt() shall return `false` indicating reuse failure.
59 * You should in that case try again, passing-in a fresh `*builder`. We'll return `true` that time.
60 *
61 * In other words:
62 * - If `*builder` is fresh, all is cool; we'll return `true`.
63 * - If `*builder` is being reused:
64 * - You must be trying to load a user message's mdt, not an internal message.
65 * - `*builder` must have been `load_mdt()`ed for the same purpose (user message, not internal message).
66 * - If reuse is possible (typical), we'll return `true`.
67 * - If reuse is not possible (atypical), we'll return `false`. Try again with fresh `*builder`.
68 *
69 * ### Fatal error possibility ###
70 * The above ignores the possibility of fatal error, meaning an input such that for internal reasons load_mdt()
71 * cannot work, regardless of `*builder` freshness. So far we've described these:
72 * - If `false` returned: no fatal error; try with fresh `*builder` as explained.
73 * - If `true` returned, and `*err_code` is falsy post-call: no fatal error; all good as explained.
74 *
75 * That leaves this one:
76 * - If `true` returned, and `*err_code` is truthy post-call: fatal error; recommend emitting to user.
77 * - This shall *not* occur if `id_or_none == 0` (for internal messages). Only user messages have enough
78 * degrees of freedom as to overload the mdt conventions we've established internally.
79 *
80 * @param builder
81 * A `MessageBuilder`. If `id_or_none == 0`, it must be fresh (not previously `load_mdt()`ed).
82 * Else it may be fresh or previously `load_mdt()`ed; in the latter case `id_or_none != 0` had to have been
83 * the case as well. / If we return `true`, `*builder` will have been loaded with a filled-out
84 * `schema::detail::StructuredMessage`.
85 * @param internal_msg_builder_or_null
86 * Must be null if and only if `id_or_none != 0`, indicating we're loading a user message's mdt. Else
87 * we're loading an internal message. In that case the post-condition is: we return `true` (always succeed); and
88 * `*internal_msg_builder_or_null` is a capnp-`Builder` for the
89 * `schema::detail::StructuredMessage::InternalMessageBody` node inside `*builder`. It is the return value of
90 * `.initInternalMessageBody()`, but that node's insides have not been filled further. The caller should
91 * use the `Builder` to set the particulars of the internal message per schema (see `structured_msg.capnp`).
92 * @param err_code
93 * To set, if and only if returning `true` (see above). If null behavior is undefined (assertion may trip).
94 * As of this writing generated codes:
95 * error::Code::S_SERIALIZE_FAILED_SPLIT_ENCODING_TOO_BIG (a Split_segment record's field's value does not
96 * fit the chosen capnp-encoding type's bit-width);
97 * error::Code::S_SERIALIZE_FAILED_SPLIT_SEGS_TOO_MANY (the mdt in total, due to its variable-length
98 * parts -- in practice the `*split_segs`-encoding list as of this writing -- does not fit `*builder`'s
99 * fixed-size area; a 2nd segment would be needed => this error).
100 * @param session_token
101 * The token to load into `*builder`.
102 * @param originating_msg_id_or_none
103 * Message ID of the in-message to which this one responds or which this one otherwise references; or 0
104 * if none.
105 * @param id_or_none
106 * Message ID of the user message whose mdt we're loading; or 0 to indicate we're loading an internal message.
107 * @param n_serialization_segments_or_none
108 * Must be 0 if and only if `id_or_none == 0`, indicating we're loading an internal message. Else we're
109 * loading a user message. In that case this is the number of (sub-)segments composing the user message's
110 * payload (this is 1 or higher). Some of these (sub-)segments may need to be re-joined by the receiver before
111 * being used as actual capnp-serialization segments; in which case this info is in `split_segs`.
112 * @param split_segs
113 * Must be null and is otherwise ignored if `id_or_none == 0` (internal message case). Else it's a
114 * user message's mdt; in which case: If `split_segs` is null, then no splitting of segments was needed, hence
115 * no re-joining is needed on the opposing side; otherwise it is a list (by convention of size at least 1)
116 * describing the split structure. See #Split_segments doc header for details.
117 * @return See above: `true` means success, `false` means retry sans reuse.
118 */
119bool load_mdt(Capped_sz_capnp_message_builder* builder,
121 Error_code* err_code,
122 const Session_token& session_token,
123 msg_id_t originating_msg_id_or_none,
124 msg_id_t id_or_none = 0, size_t n_serialization_segments_or_none = 0,
125 const Split_segments* split_segs = nullptr);
126
127} // namespace ipc::transport::struc
Builder< ipc::shm::classic::Pool_arena > Builder
Convenience alias: transport::struc::shm::Builder that works with boost.ipc.shm pools from ipc::shm::...
Definition: classic_fwd.hpp:36
Sub-module of Flow-IPC module ipc::transport providing transmission of structured messages specifical...
Definition: channel.cpp:31
std::vector< Split_segment > Split_segments
A simple data structure describing the segments (if any) in a Segment_bufs (or similar) structure whi...
Definition: struc_fwd.hpp:185
boost::uuids::uuid Session_token
A type used by struc::Channel for internal safety/security/auth needs.
Definition: struc_fwd.hpp:121
bool load_mdt(Capped_sz_capnp_message_builder *builder, schema::detail::StructuredMessage::InternalMessageBody::Builder *internal_msg_builder_or_null, Error_code *err_code, const Session_token &session_token, msg_id_t originating_msg_id_or_none, msg_id_t id_or_none, size_t n_serialization_segments_or_none, const Split_segments *split_segs)
Given user- or internal-message-describing metadata values as arguments, loads (via the provided capn...
Definition: msg_impl.cpp:43
uint64_t msg_id_t
Message ID uniquely identifying outgoing message (Msg_out, among all other Msg_outs),...
Definition: struc_fwd.hpp:215
flow::Error_code Error_code
Short-hand for flow::Error_code which is very common.
Definition: common.hpp:313