Flow-IPC 3.0.0
Flow-IPC project: Full implementation reference.
server_session_adapter.hpp
Go to the documentation of this file.
1/* Flow-IPC: Sessions
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
22
24{
25
26// Types.
27
28/**
29 * `sync_io`-pattern counterpart to async-I/O-pattern session::Server_session types and all their SHM-aware variations
30 * (at least shm::classic::Server_session et al and shm::arena_lend::jemalloc::Server_session et al). In point of fact:
31 * - Use this if and only if you desire a `sync_io`-pattern style of being informed of async events from a
32 * `Server_session` of any kind. For example, you may find this convenient if your event loop is an old-school
33 * reactor using `poll()` or `epoll_wait()`. This affects exactly the following APIs:
34 * - `Server_session` reporting a session-hosing error via on-error handler.
35 * - Set up via init_handlers().
36 * - `Server_session` reporting a channel having been passively-opened via that handler.
37 * - Set up via init_handlers().
38 * - This Server_session_adapter *adapts* a `Server_session` (earlier filled-out by
39 * Session_server_adapter::async_accept()) stored within `*this`. All APIs excluding the above -- that is to
40 * say all non-async APIs -- are to be invoked via core() accessor.
41 * - Trying to use `core()->init_handlers()` leads to undefined behavior.
42 *
43 * @see util::sync_io doc header -- describes the general `sync_io` pattern we are following.
44 * @see Session_server_adapter which prepares useful objects of this type.
45 * @see session::Server_session_mv, session::Server_session, et al.
46 *
47 * In this particular case (see below) `sync_io::X` is internally built on `X`, so it does not avoid background
48 * threads and offers no perf benefit. So the reason to use `sync_io::X` here would be that you've got an
49 * old-school reactor event loop with a `poll()` or `epoll_wait()`, in which case the `sync_io` API may be easier
50 * to integrate. Otherwise `X` does the same job with a smaller API.
51 *
52 * To use it:
53 * - Determine the type of your desired Session_server_adapter. For example, if you deal with
54 * sessions of type `session::shm::classic::Server_session<knobs>`, then use
55 * `S = Session_server_adapter<session::shm::classic::Session_server<knobs>>`.
56 * - From this obtain the desired type of `*this`: `using T = S::Session_obj`.
57 * - Construct a blank `T t` (via default ctor) -- a/k/a `*this`.
58 * - Use `s.async_accept(&t, ...)` (where `s` is an `S`), targeting `*this`. On success `*this` is ready to use,
59 * in almost-PEER state.
60 * - Set up `sync_io` pattern using start_ops() (and if needed precede it with replace_event_wait_handles()).
61 * - Call init_handlers(), analogously to async-I/O Server_session_mv::init_handlers(). As with an async-I/O
62 * `Server_session` you will need to provide:
63 * - Error handler (though it will be invoked synchronously per `sync_io` pattern).
64 * - (Optional -- if you want to enable channel passive-open): Channel passive-open handler
65 * (though it will be invoked via... ditto).
66 * - Be ready for error handler to fire (in `sync_io` style).
67 * - Be ready for passive-channel-open handler to fire (in `sync_io` style).
68 * - Use `core()->` for all other API needs (e.g., `open_channel()`, `session_shm()` -- if SHM-aware).
69 *
70 * ### Internal implementation ###
71 * Normally this would not be in the public docs for this public-use class, but indulge us...
72 *
73 * ...by reading an equally applicable note in Client_session_adapter doc header.
74 *
75 * @tparam Session
76 * The async-I/O `Server_session` concrete type being adapted. As of this writing that would be one of
77 * at least: `session::Server_session<knobs>`, `session::shm::classic::Server_session<knobs>`,
78 * `session::shm::arena_lend::jemalloc::Server_session<knobs>`. We would recommend the technique shown in the
79 * above doc header involving Session_server_adapter::Session_obj. This will enable nice code reuse and
80 * be conducive to generic programming.
81 */
82template<typename Session>
84 private Session_adapter<Session>,
85 private boost::noncopyable // There's a to-do to make it movable.
86{
87private:
88 // Types.
89
90 /// Our main base.
92
93public:
94 // Types.
95
96 /// Short-hand, for generic programming et al, for template parameter `Session`.
98
99 /// Useful for generic programming, the async-I/O-pattern counterpart to `*this` type.
101 /// You may disregard.
103
104 // Constructors/destructor.
105
106 /// Forwards to the #Session_obj default ctor.
108
109 // Methods.
110
111 /**
112 * All notes from Client_session_adapter::start_ops() apply equally.
113 *
114 * @tparam Event_wait_func_t
115 * See above.
116 * @param ev_wait_func
117 * See above.
118 * @return See above.
119 */
120 template<typename Event_wait_func_t>
121 bool start_ops(Event_wait_func_t&& ev_wait_func);
122
123 /**
124 * All notes from Client_session_adapter::replace_event_wait_handles() apply equally.
125 *
126 * @tparam Create_ev_wait_hndl_func
127 * See above.
128 * @param create_ev_wait_hndl_func
129 * See above.
130 * @return See above.
131 */
132 template<typename Create_ev_wait_hndl_func>
133 bool replace_event_wait_handles(const Create_ev_wait_hndl_func& create_ev_wait_hndl_func);
134
135 /**
136 * Acts identically to all overloads of Server_session_mv::init_handlers(), except that the completion handler(s)
137 * are invoked in the `sync_io`-pattern fashion, synchronously inside an async-wait performed by you and
138 * reported via `(*on_active_ev_func)()`. Returns `false` if invoked before start_ops() in addition to the
139 * possible reasons per Server_session_mv::init_handlers().
140 *
141 * @tparam Args
142 * See above.
143 * @param args
144 * See above.
145 * @return See above.
146 */
147 template<typename... Args>
148 bool init_handlers(Args&&... args);
149
150 /**
151 * The adapted mutable #Session_obj. It is safe to access any API except for `core()->init_handlers()` (undefined
152 * behavior); use `this->init_handlers()` instead. Remember that start_ops() is required first.
153 *
154 * @return See above.
155 */
156 Session_obj* core();
157
158 /**
159 * The adapted immutable #Session_obj. Remember that start_ops() is required first.
160 *
161 * @return See above.
162 */
163 const Session_obj* core() const;
164
165 // The LOG_*() macros don't see Log_context::get_log*() from base otherwise....
166 using Base::get_logger;
168}; // class Server_session_adapter
169
170// Free functions: in *_fwd.hpp.
171
172// Template implementations.
173
174template<typename Session>
176
177template<typename Session>
178template<typename Event_wait_func_t>
179bool Server_session_adapter<Session>::start_ops(Event_wait_func_t&& ev_wait_func)
180{
181 return Base::start_ops(std::move(ev_wait_func));
182} // Server_session_adapter::start_ops()
183
184template<typename Session>
185template<typename Create_ev_wait_hndl_func>
187 (const Create_ev_wait_hndl_func& create_ev_wait_hndl_func)
188{
189 return Base::replace_event_wait_handles(create_ev_wait_hndl_func);
190}
191
192template<typename Session>
193template<typename... Args>
195{
196 return Base::init_handlers(std::forward<Args>(args)...);
197}
198
199template<typename Session>
202{
203 return Base::core();
204}
205
206template<typename Session>
209{
210 return const_cast<Server_session_adapter*>(this)->core();
211}
212
213template<typename Session>
214std::ostream& operator<<(std::ostream& os,
216{
217 return os << "SIO@" << static_cast<const void*>(&val) << " srv_sess[" << (*(val.core())) << ']';
218}
219
220} // namespace ipc::session::sync_io
A documentation-only concept defining the local side of an IPC conversation (session) with another en...
Definition: session.hpp:217
sync_io-pattern counterpart to async-I/O-pattern session::Server_session types and all their SHM-awar...
bool replace_event_wait_handles(const Create_ev_wait_hndl_func &create_ev_wait_hndl_func)
All notes from Client_session_adapter::replace_event_wait_handles() apply equally.
Session_obj * core()
The adapted mutable Session_obj.
typename Base::Session_obj Session_obj
Short-hand, for generic programming et al, for template parameter Session.
bool init_handlers(Args &&... args)
Acts identically to all overloads of Server_session_mv::init_handlers(), except that the completion h...
bool start_ops(Event_wait_func_t &&ev_wait_func)
All notes from Client_session_adapter::start_ops() apply equally.
Server_session_adapter()
Forwards to the Session_obj default ctor.
Internal-use workhorse containing common elements of Client_session_adapter and Server_session_adapte...
const flow::log::Component & get_log_component() const
See flow::log::Log_context.
transport::Null_peer Sync_io_obj
See, e.g., Client_session_adapter.
flow::log::Logger * get_logger() const
See flow::log::Log_context.
Session Session_obj
See, e.g., Client_session_adapter.
Session_obj Async_io_obj
See, e.g., Client_session_adapter.
Dummy type for use as a template param to Channel when either the blobs pipe or handles pipe is disab...
Definition: channel.hpp:1137
sync_io-pattern counterparts to async-I/O-pattern object types in parent namespace ipc::session.
std::ostream & operator<<(std::ostream &os, const Server_session_adapter< Session > &val)
Prints string representation of the given Server_session_adapter to the given ostream.