Flow-IPC 1.0.2
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 * As is generally the case when choosing `sync_io::X` versus `X`, we recommend using `X` due to it being easier.
48 * In this particular case (see below) there is no perf benefit to using `sync_io::X`, either, so the only reason
49 * to use `sync_io::X` in this case would be because you've got an old-school reactor event loop with
50 * a `poll()` or `epoll_wait()`, in which case the `sync_io` API may be easier to integrate.
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::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)`, targeting `*this`. On success `*this` is ready to use, in almost-PEER state.
59 * - Set up `sync_io` pattern using start_ops() (and if needed precede it with replace_event_wait_handles()).
60 * - Call init_handlers(), analogously to async-I/O Server_session_mv::init_handlers(). As with an async-I/O
61 * `Server_session` you will need to provide:
62 * - Error handler (though it will be invoked synchronously per `sync_io` pattern).
63 * - (Optional -- if you want to enable channel passive-open): Channel passive-open handler
64 * (though it will be invoked via... ditto).
65 * - Be ready for error handler to fire (in `sync_io` style).
66 * - Be ready for passive-channel-open handler to fire (in `sync_io` style).
67 * - Use `core()->` for all other API needs (e.g., `open_channel()`, `session_shm()` -- if SHM-aware).
68 *
69 * ### Internal implementation ###
70 * Normally this would not be in the public docs for this public-use class, but indulge us...
71 *
72 * ...by reading an equally applicable note in Client_session_adapter doc header.
73 *
74 * @tparam Session
75 * The async-I/O `Server_session` concrete type being adapted. As of this writing that would be one of
76 * at least: `session::Server_session<knobs>`, `session::shm::classic::Server_session<knobs>`,
77 * `session::shm::jemalloc::Server_session<knobs>`. We would recommend the technique shown in the
78 * above doc header involving Session_server_adapter::Session_obj. This will enable nice code reuse and
79 * be conducive to generic programming.
80 */
81template<typename Session>
83 private Session_adapter<Session>,
84 private boost::noncopyable // There's a to-do to make it movable.
85{
86private:
87 // Types.
88
89 /// Our main base.
91
92public:
93 // Types.
94
95 /// Short-hand, for generic programming et al, for template parameter `Session`.
97
98 /// Useful for generic programming, the async-I/O-pattern counterpart to `*this` type.
100 /// You may disregard.
102
103 // Constructors/destructor.
104
105 /// Forwards to the #Session_obj default ctor.
107
108 // Methods.
109
110 /**
111 * All notes from Client_session_adapter::start_ops() apply equally.
112 *
113 * @tparam Event_wait_func_t
114 * See above.
115 * @param ev_wait_func
116 * See above.
117 * @return See above.
118 */
119 template<typename Event_wait_func_t>
120 bool start_ops(Event_wait_func_t&& ev_wait_func);
121
122 /**
123 * All notes from Client_session_adapter::replace_event_wait_handles() apply equally.
124 *
125 * @tparam Create_ev_wait_hndl_func
126 * See above.
127 * @param create_ev_wait_hndl_func
128 * See above.
129 * @return See above.
130 */
131 template<typename Create_ev_wait_hndl_func>
132 bool replace_event_wait_handles(const Create_ev_wait_hndl_func& create_ev_wait_hndl_func);
133
134 /**
135 * Acts identically to all overloads of Server_session_mv::init_handlers(), except that the completion handler(s)
136 * are invoked in the `sync_io`-pattern fashion, synchronously inside an async-wait performed by you and
137 * reported via `(*on_active_ev_func)()`. Returns `false` if invoked before start_ops() in addition to the
138 * possible reasons per Server_session_mv::init_handlers().
139 *
140 * @tparam Args
141 * See above.
142 * @param args
143 * See above.
144 * @return See above.
145 */
146 template<typename... Args>
147 bool init_handlers(Args&&... args);
148
149 /**
150 * The adapted mutable #Session_obj. It is safe to access any API except for `core()->init_handlers()` (undefined
151 * behavior); use `this->init_handlers()` instead. Remember that start_ops() is required first.
152 *
153 * @return See above.
154 */
155 Session_obj* core();
156
157 /**
158 * The adapted immutable #Session_obj. Remember that start_ops() is required first.
159 *
160 * @return See above.
161 */
162 const Session_obj* core() const;
163
164 // The LOG_*() macros don't see Log_context::get_log*() from base otherwise....
165 using Base::get_logger;
167}; // class Server_session_adapter
168
169// Free functions: in *_fwd.hpp.
170
171// Template implementations.
172
173template<typename Session>
175
176template<typename Session>
177template<typename Event_wait_func_t>
178bool Server_session_adapter<Session>::start_ops(Event_wait_func_t&& ev_wait_func)
179{
180 return Base::start_ops(std::move(ev_wait_func));
181} // Session_adapter::start_ops()
182
183template<typename Session>
184template<typename Create_ev_wait_hndl_func>
186 (const Create_ev_wait_hndl_func& create_ev_wait_hndl_func)
187{
188 return Base::replace_event_wait_handles(create_ev_wait_hndl_func);
189}
190
191template<typename Session>
192template<typename... Args>
194{
195 return Base::init_handlers(std::forward<Args>(args)...);
196}
197
198template<typename Session>
201{
202 return Base::core();
203}
204
205template<typename Session>
208{
209 return const_cast<Server_session_adapter*>(this)->core();
210}
211
212template<typename Session>
213std::ostream& operator<<(std::ostream& os,
215{
216 return os << "SIO@" << static_cast<const void*>(&val) << " srv_sess[" << (*(val.core())) << ']';
217}
218
219} // namespace ipc::session::sync_io
A documentation-only concept defining the local side of an IPC conversation (session) with another en...
Definition: session.hpp:216
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:1000
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.