Flow-IPC
1.0.2
Flow-IPC project: Full implementation reference.
session
shm
shm_fwd.hpp
Go to the documentation of this file.
1
/* Flow-IPC: Shared Memory
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
#pragma once
20
21
/**
22
* ipc::session sub-namespace that groups together facilities for SHM-backed sessions, particularly augmenting
23
* #Client_session, #Server_session, and Session_server classes by providing SHM-backed zero-copy functionality.
24
* ipc::session::shm is itself empty or almost empty; but for each possible SHM provider there is a further
25
* sub-namespace; for example ipc::session::shm::classic.
26
*
27
* ### Background ###
28
* ipc::shm provides SHM facilities, including ipc::shm::classic and ipc::shm::arena_lend::jemalloc, that can be used
29
* stand-alone, without ipc::session. As with ipc::transport, though, this is not very convenient.
30
* ipc::session is well integrated with ipc::shm in that it provides certain pre-made arenas and simplifies
31
* transmission of handles to SHM-constructed objects and allows to place transport::struc::Channel
32
* out-messages into SHM instead of heap -- achieving full zero-copy if desired. ipc::session::shm is where
33
* this support lives.
34
*
35
* ### Details ###
36
* If you want these features, everything in the "Overview of relevant APIs" section (of ipc::session doc header)
37
* still applies identically, except you shall choose different types rather than #Client_session, #Server_session,
38
* Session_server. Firstly decide which SHM-provider; as of this writing ipc::shm::classic::Pool_arena or
39
* ipc::shm::arena_lend::jemalloc. For illustration let's assume you chose the former. Then:
40
* - Use shm::classic::Client_session in place of vanilla #Client_session.
41
* - Use shm::classic::Session_server in place of vanilla Session_server.
42
* - This will emit shm::classic::Server_session in place of vanilla #Server_session.
43
*
44
* We strongly recommend making yourself aliases as shown below, then from that point on obtaining all subsequent
45
* ipc::session types via aliases contained within those aliases (and then more aliases off those
46
* aliases as needed). The idea is to have only one point in the code where the SHM-backing (or no SHM backing)
47
* of the system are specified (simply by indicating the namespace of the top-level `Session_server` or `Client_session`
48
* type of choice), so that it can be easily changed to another, a-la generic programming.
49
*
50
* Server-side:
51
*
52
* ~~~
53
* using Session_server = ipc::session::shm::classic::Session_server
54
* <...>; // Compile-time session-configuring knobs go here.
55
* // ^-- Substitute shm::arena_lend::jemalloc::Session_server or even non-zero-copy plain Session_server as desired.
56
*
57
* // From this point on, no need to mention `ipc::session` again. In particular, e.g.:
58
*
59
* using Session = typename Session_server::Server_session_obj;
60
* template<typename Message_body>
61
* using Structured_channel = typename Session::template Structured_channel<Message_body>;
62
*
63
* // Off we go! Use the types as needed.
64
*
65
* // ...
66
* Session session; // Maybe fill it out with Session_server::async_accept() following this.
67
* // ...
68
* Structured_channel<MessageSchemaRootOfTheGods> cool_channel(...);
69
* // ...
70
* ~~~
71
*
72
* Client-side:
73
*
74
* ~~~
75
* using Session = ipc::session::shm::classic::Client_session
76
* <...>; // Matching (to server-side) knobs go here.
77
* // ^-- Substitute shm::arena_lend::jemalloc::Client_session or even non-zero-copy plain Client_session as desired.
78
*
79
* // From this point on, no need to mention `ipc::session` again. In particular, e.g.:
80
*
81
* using Session = typename Session_server::Server_session_obj;
82
* template<typename Message_body>
83
* using Structured_channel = typename Session::template Structured_channel<Message_body>;
84
*
85
* // Off we go! Use the types as needed.
86
*
87
* // ...
88
* Session session(...); // Maybe .sync_connect() following this.
89
* // ...
90
* Structured_channel<MessageSchemaRootOfTheGods> cool_channel(...);
91
* // ...
92
* ~~~
93
*
94
* Entering PEER state is exactly identical to the vanilla APIs (the differences are under the hood).
95
* Once in PEER state, however, the added capabilities become available; these are on top of
96
* the Session concept API, in the form added members including methods. A quick survey:
97
* - Each of shm::classic::Client_session and shm::classic::Server_session is a shm::classic::Session_mv
98
* (alias and sub-class respectively). shm::classic::Session::session_shm() and
99
* shm::classic::Session::app_shm() each access the pre-made SHM arenas of the aforementioned scopes
100
* (per-session and per-app respectively). Call `construct<T>(...)` on either to SHM-construct an object.
101
* Use an STL-compliant `T` with `Session::Allocator` and shm::stl::Arena_activator aids to store
102
* sophisticated data structures in SHM. Use shm::classic::Session_mv::lend_object() to prepare to
103
* transmit an outer SHM-handle to such a `T` to the opposing shm::classic::Session. On that side use
104
* shm::classic::Session_mv::borrow_object() to recover an equivalent outer SHM-handle. The `T` shall be
105
* returned to the SHM-arena once *both* processes are done with it. The handle acts like a
106
* cross-process-GCing `shared_ptr` (and is, in fact, `shared_ptr<T>`).
107
* - This enables manually-constructing structures and transmitting them from one session participant to the
108
* other.
109
* - On the borrower side one should define `T` in terms of `"Session::Borrower_allocator"` instead of
110
* `"Session::Allocator"`. (With SHM-classic they are the same type; but with arena-lending SHM providers,
111
* SHM-jemalloc at the moment, they are not.)
112
* - Suppose you have opened a channel C between your two peer objects. Suppose you upgrade it to a
113
* transport::struc::Channel. Without SHM, your only out-of-the-box choice for out-message serialization
114
* is the heap (transport::struc::Channel_base::Serialize_via_heap-tag ctor). This involves copying into
115
* and out of the low-level IPC transport. With SHM you can now do better: as you mutate your out-message,
116
* it will be invisibly backed by SHM-allocated segment(s); and when you `send()` and receive it, only
117
* a small handle will be copied into and out of the IPC transport (again invisibly to you; it'll just happen).
118
* To set it up simply use `transport::struc::Channel_base::Serialize_via_session_shm`-tag
119
* (or possibly `Serialize_via_app_shm`-tag) ctor of `struc::Channel`.
120
* - This enables zero-copy-enabled/arbitrarily-large structured messages through channels in your
121
* shm::classic::Client_session<->shm::classic::Server_session session.
122
*
123
* That's with SHM-classic. With SHM-jemalloc it is all quite similar; basically just replace `classic` with
124
* `arena_lend::jemalloc` in various names above (more or less).
125
* Reminder: it is easiest and most stylish to not have to a big search/replace but rather to use the
126
* top-level alias technique shown in the above code snippets.
127
*
128
* Further details about SHM-classic versus SHM-jemalloc (etc.) are documented elsewhere.
129
* Preview: `arena_lend::jemalloc` is safer and faster (backed by the commercial-grade "jemalloc" `malloc()` impl
130
* algorithm), though it does not allow `app_shm()->construct()` (per-app-scope allocation) on the client side (via
131
* shm::arena_lend::jemalloc::Client_session -- available only shm::arena_lend::jemalloc::Server_session); there's
132
* no such method as `shm::arena_lend::jemalloc::Client_session::app_shm()`.
133
*
134
* ### One more small thing: logging addendum for SHM-jemalloc users ###
135
* This is really a footnote in importance, though there's no good reason to ignore it either.
136
* A certain aspect of SHM-jemalloc (and potentially more future arena-lending-type SHM-providers) requires
137
* singleton-based (essentially, global) operation. You need not worry about it... it just works... except
138
* it (like all Flow-IPC code) logs; and thus needs to know to which `Logger` to log. Since various ipc::session
139
* objects don't want to presume whose `Logger` is the one to impose on this shared global guy -- plus the
140
* setter is not thread-safe -- we ask that you do so sometime before any ipc::session::arena_lend object creation.
141
* Namely just do this:
142
*
143
* ~~~
144
* ipc::session::shm::arena_lend::Borrower_shm_pool_collection_repository_singleton::get_instance()
145
* .set_logger(...); // ... = pointer to your Logger of choice. Null to disable logging (which is default anyway).
146
* ~~~
147
*
148
* If SHM-jemalloc is not used, this call is harmless.
149
*/
150
namespace
ipc::session::shm
151
{
152
153
// Types.
154
155
// Find doc headers near the bodies of these compound types.
156
157
template
<
typename
Arena>
158
struct
Arena_to_shm_session;
159
160
}
// namespace ipc::session::shm
ipc::session::shm
ipc::session sub-namespace that groups together facilities for SHM-backed sessions,...
Definition:
classic_fwd.hpp:24
Generated on Sat Mar 30 2024 02:06:54 for Flow-IPC by
1.9.4