Flow 1.0.2
Flow project: Full implementation reference.
peer_socket.hpp
Go to the documentation of this file.
1/* Flow
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
23
25{
26
27/**
28 * A net_flow::Peer_socket that adds integration with boost.asio. See net_flow::Node for a discussion of the topic of
29 * boost.asio integration. A net_flow::asio::Peer_socket *is* a net_flow::Peer_socket with all that functionality, plus
30 * APIs (such as async_send(), async_receive()) that accomplish boost.asio-style asynchronous operations with a
31 * standard `boost::asio::io_service` (a/k/a flow::util::Task_engine).
32 *
33 * As of this writing, `asio::Peer_socket::Ptr`s are generated by `asio::Node::connect()`,
34 * `asio::Server_socket::accept()`, and their derivatives. The underlying `io_service` (a/k/a flow::util::Task_engine)
35 * is carried forward from the factory object that generated and returned the `Ptr`. It can be overwritten via
36 * set_async_task_engine().
37 */
40 // Note: can't derive util::Shared_ptr_alias_holder<>, because superclass already did it (doc header disallows this).
41{
42public:
43 // Types.
44
45 /// Short-hand for `shared_ptr` to Peer_socket.
46 using Ptr = boost::shared_ptr<Peer_socket>;
47
48 // Constructors/destructor.
49
50 /// Boring `virtual` destructor as in superclass. See notes there.
51 ~Peer_socket() override;
52
53 // Methods.
54
55 /**
56 * Pointer (possibly null) for the flow::util::Task_engine used by any coming `async_*()` I/O calls.
57 *
58 * ### Thread safety (operating on a given Node) ###
59 *
60 * - set_async_task_engine() is the only way to change the returned value, upon construction.
61 * - It is not safe to call set_async_task_engine() at the same time as async_task_engine().
62 * - Define "any async op" as `async_*()` in this class, including actions it takes
63 * in the background (asynchronously).
64 * - async_task_engine() must return the same value -- and *not* null -- throughout "any async op."
65 * - Put simply, a null `Task_engine` is allowed, but a null cannot be used when
66 * performing an async op. Furthermore, set_async_task_engine() is unsafe through any of those and through
67 * async_task_engine() itself.
68 *
69 * Informal tip: Same as in doc header for Node::async_task_engine().
70 *
71 * @return Null or non-null pointer to flow::util::Task_engine.
72 */
74
75 /**
76 * Read-only version of async_task_engine().
77 *
78 * @return Reference to read-only `*(async_task_engine())`.
79 */
81
82 /**
83 * Overwrites the value to be returned by next async_task_engine().
84 *
85 * See async_task_engine() doc header before using this.
86 *
87 * @param target_async_task_engine
88 * See async_task_engine().
89 */
90 void set_async_task_engine(util::Task_engine* target_async_task_engine);
91
92 /**
93 * boost.asio-style asynchronous version that essentially performs non-`null_buffers`
94 * net_flow::Peer_socket::sync_receive() in the background and invokes the given handler via the saved
95 * `Task_engine *(async_task_engine())`, as if by `Task_engine::post()`.
96 *
97 * The semantics are identical to the similar `sync_receive()`, except that the operation does not block the
98 * calling thread; and the results are delivered to the supplied handler `on_result` instead of to the caller.
99 *
100 * @tparam Rep
101 * See net_flow::Peer_socket::receive().
102 * @tparam Period
103 * See net_flow::Peer_socket::receive().
104 * @tparam Mutable_buffer_sequence
105 * See net_flow::Peer_socket::receive().
106 * @tparam Handler
107 * A type such that if `Handler h`, then a function equivalent to `{ h(err_code, n); }` can
108 * be `post()`ed onto an `Task_engine`, with `const Error_code& err_code` and `size_t n`.
109 * @param target
110 * See net_flow::Peer_socket::receive().
111 * @param on_result
112 * Handler to be executed asynchronously within the saved `Task_engine`.
113 * The error code and bytes-transmitted values passed to it, in that order, are identical
114 * to those out-arg/returned values in net_flow::Peer_socket::sync_receive().
115 * Note: This overload corresponds to the non-`null_buffers` `sync_receive()` overload.
116 * Note: Use `bind_executor(S, F)` to bind your handler to the util::Strand `S`.
117 * @param max_wait
118 * See net_flow::Peer_socket::sync_receive().
119 */
120 template<typename Rep, typename Period, typename Mutable_buffer_sequence, typename Handler>
121 void async_receive(const Mutable_buffer_sequence& target,
122 const boost::chrono::duration<Rep, Period>& max_wait,
123 Handler&& on_result);
124
125 /**
126 * boost.asio-style asynchronous version that essentially performs a `null_buffers`
127 * net_flow::Peer_socket::sync_receive() in the background and invokes the given handler via the saved
128 * `Task_engine *(async_task_engine())`, as if by `Task_engine::post()`.
129 *
130 * The semantics are identical to the similar `sync_receive()`, except that the operation does not block the
131 * calling thread; and the results are delivered to the supplied handler `on_result` instead of to the caller.
132 *
133 * @tparam Rep
134 * See net_flow::Peer_socket::receive().
135 * @tparam Period
136 * See net_flow::Peer_socket::receive().
137 * @tparam Handler
138 * A type such that if `Handler h`, then a function equivalent to `{ h(err_code, n); }` can
139 * be `post()`ed onto an `Task_engine`, with `const Error_code& err_code` and `size_t n`.
140 * @param on_result
141 * Handler to be executed asynchronously within the saved `Task_engine`.
142 * The error code and bytes-transmitted values passed to it, in that order, are identical
143 * to those out-arg/returned values in net_flow::Peer_socket::sync_receive().
144 * Note: This overload corresponds to the `null_buffers` `sync_receive()` overload.
145 * Therefore, the bytes-transmitted value passed to the handler is always 0.
146 * Note: Use `bind_executor(S, F)` to bind your handler to the util::Strand `S`.
147 * @param max_wait
148 * See net_flow::Peer_socket::sync_receive().
149 */
150 template<typename Rep, typename Period, typename Handler>
151 void async_receive(const boost::asio::null_buffers&,
152 const boost::chrono::duration<Rep, Period>& max_wait,
153 Handler&& on_result);
154
155 /**
156 * Equivalent to `async_receive(target, duration::max(), on_result)`; i.e., `async_receive()`
157 * with no timeout.
158 *
159 * @tparam Mutable_buffer_sequence
160 * See other async_receive().
161 * @tparam Handler
162 * See other async_receive().
163 * @param target
164 * See other async_receive().
165 * @param on_result
166 * See other async_receive().
167 */
168 template<typename Mutable_buffer_sequence, typename Handler>
169 void async_receive(const Mutable_buffer_sequence& target, Handler&& on_result);
170
171 /**
172 * Equivalent to `async_receive(null_buffers(), duration::max(), on_result)`; i.e., `async_receive(null_buffers)`
173 * with no timeout.
174 *
175 * @tparam Handler
176 * See other async_receive().
177 * @param on_result
178 * See other async_receive().
179 */
180 template<typename Handler>
181 void async_receive(const boost::asio::null_buffers&, Handler&& on_result);
182
183 /**
184 * boost.asio-style asynchronous version that essentially performs non-`null_buffers`
185 * net_flow::Peer_socket::sync_send() in the background and invokes the given handler via the saved
186 * `Task_engine *(async_task_engine())`, as if by `Task_engine::post()`.
187 *
188 * The semantics are identical to the similar `sync_send()`, except that the operation does not block the
189 * calling thread; and the results are delivered to the supplied handler `on_result` instead of to the caller.
190 *
191 * @tparam Rep
192 * See net_flow::Peer_socket::send().
193 * @tparam Period
194 * See net_flow::Peer_socket::send().
195 * @tparam Const_buffer_sequence
196 * See net_flow::Peer_socket::send().
197 * @tparam Handler
198 * A type such that if `Handler h`, then a function equivalent to `{ h(err_code, n); }` can
199 * be `post()`ed onto an `Task_engine`, with `const Error_code& err_code` and `size_t n`.
200 * @param source
201 * See net_flow::Peer_socket::send().
202 * @param on_result
203 * Handler to be executed asynchronously within the saved `Task_engine`.
204 * The error code and bytes-transmitted values passed to it, in that order, are identical
205 * to those out-arg/returned values in net_flow::Peer_socket::sync_send().
206 * Note: This overload corresponds to the non-`null_buffers` `sync_send()` overload.
207 * Note: Use `bind_executor(S, F)` to bind your handler to the util::Strand `S`.
208 * @param max_wait
209 * See net_flow::Peer_socket::sync_send().
210 */
211 template<typename Rep, typename Period, typename Const_buffer_sequence, typename Handler>
212 void async_send(const Const_buffer_sequence& source,
213 const boost::chrono::duration<Rep, Period>& max_wait,
214 Handler&& on_result);
215
216 /**
217 * boost.asio-style asynchronous version that essentially performs a `null_buffers`
218 * net_flow::Peer_socket::sync_send() in the background and invokes the given handler via the saved
219 * `Task_engine *(async_task_engine())`, as if by `Task_engine::post()`.
220 *
221 * The semantics are identical to the similar `sync_send()`, except that the operation does not block the
222 * calling thread; and the results are delivered to the supplied handler `on_result` instead of to the caller.
223 *
224 * @tparam Rep
225 * See net_flow::Peer_socket::send().
226 * @tparam Period
227 * See net_flow::Peer_socket::send().
228 * @tparam Handler
229 * A type such that if `Handler h`, then a function equivalent to `{ h(err_code, n); }` can
230 * be `post()`ed onto an `Task_engine`, with `const Error_code& err_code` and `size_t n`.
231 * @param on_result
232 * Handler to be executed asynchronously within the saved `Task_engine`.
233 * The error code and bytes-transmitted values passed to it, in that order, are identical
234 * to those out-arg/returned values in net_flow::Peer_socket::sync_send().
235 * Note: This overload corresponds to the `null_buffers` `sync_send()` overload.
236 * Therefore, the bytes-transmitted value passed to the handler is always 0.
237 * Note: Use `bind_executor(S, F)` to bind your handler to the util::Strand `S`.
238 * @param max_wait
239 * See net_flow::Peer_socket::sync_send().
240 */
241 template<typename Rep, typename Period, typename Handler>
242 void async_send(const boost::asio::null_buffers&,
243 const boost::chrono::duration<Rep, Period>& max_wait,
244 Handler&& on_result);
245
246 /**
247 * Equivalent to `async_send(target, duration::max(), on_result)`; i.e., `async_send()`
248 * with no timeout.
249 *
250 * @tparam Const_buffer_sequence
251 * See other async_send().
252 * @tparam Handler
253 * See other async_send().
254 * @param source
255 * See other async_send().
256 * @param on_result
257 * See other async_send().
258 */
259 template<typename Const_buffer_sequence, typename Handler>
260 void async_send(const Const_buffer_sequence& source, Handler&& on_result);
261
262 /**
263 * Equivalent to `async_send(null_buffers(), duration::max(), on_result)`; i.e., `async_send(null_buffers)`
264 * with no timeout.
265 *
266 * @tparam Handler
267 * See other async_send().
268 * @param on_result
269 * See other async_send().
270 */
271 template<typename Handler>
272 void async_send(const boost::asio::null_buffers&, Handler&& on_result);
273
274 /**
275 * Convenience method that polymorphically casts from `net_flow::Peer_socket::Ptr` to
276 * subclass pointer `net_flow::asio::Peer_socket::Ptr`.
277 * Behavior undefined if `sock` is not actually of the latter type.
278 * With this, one needn't do verbose `static_[pointer_]cast<>` or similar conversions.
279 *
280 * @param sock
281 * Handle to a `sock` such that the true underlying concrete type is net_flow::asio::Peer_socket.
282 * @return See above.
283 */
285
286private:
287
288 // Friends.
289
290 /// Similarly to the equivalent `friend` in net_flow::Peer_socket.
291 friend class Node;
292 /// As of this writing, it is needed for Node::sock_create_forward_plus_ctor_args().
293 friend class net_flow::Node;
294
295 // Friend of Peer_socket: For access to private alias Int_state.
296 friend std::ostream& operator<<(std::ostream& os, const Peer_socket* sock);
297
298 // Types.
299
300 /// Short-hand for the `Mutable_buffer_sequence` concrete type for class-internal code.
301 using Target_bufs = std::vector<boost::asio::mutable_buffer>;
302 /// Short-hand for a low-cost-copyable smart pointer of `Target_bufs`.
303 using Target_bufs_ptr = boost::shared_ptr<Target_bufs>;
304 /// Short-hand for the `Const_buffer_sequence` concrete type for class-internal code.
305 using Source_bufs = std::vector<boost::asio::const_buffer>;
306 /// Short-hand for a low-cost-copyable smart pointer of `Source_bufs`.
307 using Source_bufs_ptr = boost::shared_ptr<Source_bufs>;
308 /// Short-hand for the `Task_engine`-compatible send and receive `Handler` concrete type for class-internal code.
309 using Handler_func = Function<void (const Error_code& err_code, size_t op_result)>;
310
311 // Constructors/destructor.
312
313 /**
314 * Constructs object.
315 *
316 * @param logger_ptr
317 * See superclass.
318 * @param task_engine
319 * See superclass.
320 * @param opts
321 * See superclass.
322 */
323 explicit Peer_socket(log::Logger* logger_ptr,
324 util::Task_engine* task_engine,
325 const Peer_socket_options& opts);
326
327 // Methods.
328
329 /**
330 * De-templated implementation of all `async_receive()` methods.
331 *
332 * @param target
333 * Ref-counted pointer to copy of `target` arg for non-`null_buffers` `async_receive()` methods;
334 * or null in the case of `async_receive(null_buffers)` methods.
335 * @param on_result
336 * `handler_func(on_result)`, where `on_result` is the user's `async_*()` method arg.
337 * @param wait_until
338 * See `max_wait` arg on the originating `async_receive()` method. This is absolute timeout time point
339 * derived from it; zero-valued if no timeout.
340 */
341 void async_receive_impl(Target_bufs_ptr target, Handler_func&& on_result,
342 const Fine_time_pt& wait_until);
343
344 /**
345 * De-templated implementation of all `async_send()` methods.
346 *
347 * @param source
348 * Ref-counted pointer to copy of `source` arg for non-`null_buffers` `async_send()` methods;
349 * or an empty sequence in the case of `async_send(null_buffers)` methods.
350 * @param on_result
351 * `handler_func(on_result)`, where `on_result` is the user's `async_*()` method arg.
352 * @param wait_until
353 * See `max_wait` arg on the originating `async_send()` method. This is absolute timeout time point
354 * derived from it; zero-valued if no timeout.
355 */
356 void async_send_impl(Source_bufs_ptr source, Handler_func&& on_result,
357 const Fine_time_pt& wait_until);
358
359 /**
360 * Helper that returns the `net_flow::asio::Node` that generated `*this`; unless `*this` is closed;
361 * in which case it returns null after posting an error-case invocation of the user handler `on_result`.
362 *
363 * @param on_result
364 * `handler_func(on_result)`, where `on_result` is the user's `async_*()` method arg.
365 * This will be executed if and only if null is returned. The reason for why the latter occurred is passed as
366 * the error code argument to `on_result()`.
367 * @return Non-null pointer to owning Node, if and only if it is available.
368 */
370
371 /**
372 * Returns a functor that essentially performs `post()` `on_result` onto `*async_task_engine()` in a way suitable
373 * for a boost.asio-compatible async-op.
374 *
375 * ### Rationale ###
376 * Why not simply create use `Handler_func(on_result)`? After all they have the same signature, so if the
377 * idea is to de-template our internal implementation of the various `async_*()` APIs, then that would be sufficient.
378 * Answer:
379 *
380 * We are aiming to implement a boost.asio-compatible async-op, so one way or another we'll need to `post()`
381 * a no-arg wrapper of `on_result(...);`. handler_func() returning a function that does that alone would
382 * be potentially useful in its own right. That, however, is still insufficient -- though that may not be obvious
383 * even to experienced boost.asio *users*. `Handler` and `on_result` may be associated with an executor,
384 * such as a util::Strand, which a proper boost.asio async-op API must respect when `post()`ing it onto the
385 * util::Task_engine. handler_func() takes care of that too (details omitted here; see body).
386 *
387 * Note: Failing to do the executor stuff will build, and work -- but it won't work "all the way," if `on_result`
388 * is bound to an executor like a strand. In the latter case it would result in executing `on_result()` outside
389 * the associated strand -- and hence potential thread-unsafety.
390 *
391 * @tparam Handler
392 * See async_receive() and others.
393 * @param on_result
394 * See async_receive() and others.
395 * @return Function to call from any context that will properly `post()` `on_result();` onto `*async_task_engine()`.
396 */
397 template<typename Handler>
398 Handler_func handler_func(Handler&& on_result);
399
400 // Data.
401
402 /// See async_task_engine().
404}; // class asio::Peer_socket
405
406// Free functions: in *_fwd.hpp.
407
408// Template implementations.
409
410template<typename Rep, typename Period, typename Mutable_buffer_sequence, typename Handler>
411void Peer_socket::async_receive(const Mutable_buffer_sequence& target,
412 const boost::chrono::duration<Rep, Period>& max_wait,
413 Handler&& on_result)
414{
415 assert(target.begin() != target.end());
416 async_receive_impl(Target_bufs_ptr(new Target_bufs(target.begin(), target.end())),
417 handler_func(on_result),
419}
420
421template<typename Rep, typename Period, typename Handler>
422void Peer_socket::async_receive(const boost::asio::null_buffers&,
423 const boost::chrono::duration<Rep, Period>& max_wait,
424 Handler&& on_result)
425{
428}
429
430template<typename Mutable_buffer_sequence, typename Handler>
431void Peer_socket::async_receive(const Mutable_buffer_sequence& target,
432 Handler&& on_result)
433{
434 assert(target.begin() != target.end());
435 async_receive_impl(Target_bufs_ptr(new Target_bufs(target.begin(), target.end())),
436 handler_func(on_result), Fine_time_pt());
437}
438
439template<typename Handler>
440void Peer_socket::async_receive(const boost::asio::null_buffers&, Handler&& on_result)
441{
443}
444
445template<typename Rep, typename Period, typename Const_buffer_sequence, typename Handler>
446void Peer_socket::async_send(const Const_buffer_sequence& source,
447 const boost::chrono::duration<Rep, Period>& max_wait,
448 Handler&& on_result)
449{
450 assert(source.begin() != source.end());
451 async_send_impl(Source_bufs_ptr(new Source_bufs(source.begin(), source.end())),
452 handler_func(on_result),
454}
455
456template<typename Rep, typename Period, typename Handler>
457void Peer_socket::async_send(const boost::asio::null_buffers&,
458 const boost::chrono::duration<Rep, Period>& max_wait,
459 Handler&& on_result)
460{
463}
464
465template<typename Const_buffer_sequence, typename Handler>
466void Peer_socket::async_send(const Const_buffer_sequence& source,
467 Handler&& on_result)
468{
469 assert(source.begin() != source.end());
470 async_send_impl(Source_bufs_ptr(new Source_bufs(source.begin(), source.end())),
471 handler_func(on_result), Fine_time_pt());
472}
473
474template<typename Handler>
476 (const boost::asio::null_buffers&,
477 Handler&& on_result)
478{
480}
481
482template<typename Handler>
484{
485 using boost::asio::post;
486 using boost::asio::bind_executor;
487 using boost::asio::get_associated_executor;
488
489 /* Necessary background: See our doc header Rationale section.
490 *
491 * As stated there, we have 2 interrelated jobs:
492 * - post() on_result() onto *async_task_engine(). Note on_result() takes some args, whereas anything post()ed
493 * takes no args.
494 * - When doing said post(), do it through the executor associated with `on_result`.
495 * There are 2 common situations (though not the only ones possible) worth contemplating:
496 * - If on_result is a "vanilla" handler without anything fancy, get_associated_executor(on_result) will
497 * return boost::asio::system_executor. boost.asio post() reference web page will clarify that
498 * post(E, F), where E is a Task_engine, and F is a handler associated with system_executor,
499 * will simply cause F() to be post()ed onto E (to execute ASAP on a threads doing E.run()).
500 * (We've also tested this empirically.)
501 * - If on_result is bound to a strand S, via bind_executor(S, F), get_associated_executor(on_result) will
502 * return the boost::asio::strand (flow::util::Strand) S. boost.asio doc web page about strands
503 * explains post(E, bind_executor(S, F)) will post() F onto E, with the added constraint to not execute it
504 * concurrently with any other handler also associated with S.
505 * - Other executors (not only strands) are possible, though that's more obscure.
506 *
507 * Failing to post() through get_associated_executor(on_result) -- e.g., simply just calling on_result() inside
508 * the post()ed body -- would work great in the "vanilla" case but would simply disregard the strand S in the
509 * strand case above (or whatever other executor).
510 */
511 return [this, on_result = std::move(on_result)]
512 (const Error_code& err_code, size_t op_result)
513 mutable
514 {
515 // Not safe to rely on L->R arg evaluation below; get this 1st, when we know on_result hasn't been move()d.
516 const auto executor = get_associated_executor(on_result); // Usually system_executor (vanilla) or a strand.
517 post(*(async_task_engine()),
518 bind_executor(executor,
519 [err_code, op_result, on_result = std::move(on_result)]
520 {
521 on_result(err_code, op_result);
522 }));
523 };
524} // Peer_socket::handler_func()
525
526} // namespace flow::net_flow::asio
Interface that the user should implement, passing the implementing Logger into logging classes (Flow'...
Definition: log.hpp:1291
An object of this class is a single Flow-protocol networking node, in the sense that: (1) it has a di...
Definition: node.hpp:937
A peer (non-server) socket operating over the Flow network protocol, with optional stream-of-bytes an...
A subclass of net_flow::Node that adds the ability to easily and directly use net_flow sockets in gen...
Definition: node.hpp:236
A net_flow::Peer_socket that adds integration with boost.asio.
Definition: peer_socket.hpp:41
~Peer_socket() override
Boring virtual destructor as in superclass. See notes there.
Definition: peer_socket.cpp:37
void set_async_task_engine(util::Task_engine *target_async_task_engine)
Overwrites the value to be returned by next async_task_engine().
Definition: peer_socket.cpp:53
static Ptr cast(net_flow::Peer_socket::Ptr sock)
Convenience method that polymorphically casts from net_flow::Peer_socket::Ptr to subclass pointer net...
util::Task_engine * async_task_engine()
Pointer (possibly null) for the flow::util::Task_engine used by any coming async_*() I/O calls.
Definition: peer_socket.cpp:42
void async_send(const Const_buffer_sequence &source, const boost::chrono::duration< Rep, Period > &max_wait, Handler &&on_result)
boost.asio-style asynchronous version that essentially performs non-null_buffers net_flow::Peer_socke...
boost::shared_ptr< Peer_socket > Ptr
Short-hand for shared_ptr to Peer_socket.
Definition: peer_socket.hpp:46
boost::shared_ptr< Target_bufs > Target_bufs_ptr
Short-hand for a low-cost-copyable smart pointer of Target_bufs.
std::vector< boost::asio::mutable_buffer > Target_bufs
Short-hand for the Mutable_buffer_sequence concrete type for class-internal code.
const util::Task_engine & async_task_engine_cref() const
Read-only version of async_task_engine().
Definition: peer_socket.cpp:48
util::Task_engine * m_target_task_engine
See async_task_engine().
friend std::ostream & operator<<(std::ostream &os, const Peer_socket *sock)
Prints string representation of given socket to given standard ostream and returns the latter.
void async_receive_impl(Target_bufs_ptr target, Handler_func &&on_result, const Fine_time_pt &wait_until)
De-templated implementation of all async_receive() methods.
Definition: peer_socket.cpp:61
void async_receive(const Mutable_buffer_sequence &target, const boost::chrono::duration< Rep, Period > &max_wait, Handler &&on_result)
boost.asio-style asynchronous version that essentially performs non-null_buffers net_flow::Peer_socke...
std::vector< boost::asio::const_buffer > Source_bufs
Short-hand for the Const_buffer_sequence concrete type for class-internal code.
Handler_func handler_func(Handler &&on_result)
Returns a functor that essentially performs post() on_result onto *async_task_engine() in a way suita...
Node * node_or_post_error(Handler_func &&on_result)
Helper that returns the net_flow::asio::Node that generated *this; unless *this is closed; in which c...
void async_send_impl(Source_bufs_ptr source, Handler_func &&on_result, const Fine_time_pt &wait_until)
De-templated implementation of all async_send() methods.
Peer_socket(log::Logger *logger_ptr, util::Task_engine *task_engine, const Peer_socket_options &opts)
Constructs object.
Definition: peer_socket.cpp:28
boost::shared_ptr< Source_bufs > Source_bufs_ptr
Short-hand for a low-cost-copyable smart pointer of Source_bufs.
boost::shared_ptr< Peer_socket > Ptr
Short-hand for ref-counted pointer to mutable values of type Target_type::element_type (a-la T*).
Contains classes that add boost.asio integration to the main Flow-protocol classes such as net_flow::...
Definition: node.cpp:25
Fine_time_pt chrono_duration_from_now_to_fine_time_pt(const boost::chrono::duration< Rep, Period > &dur)
Helper that takes a non-negative duration of arbitrary precision/period and converts it to Fine_durat...
Definition: util.hpp:42
boost::asio::io_service Task_engine
Short-hand for boost.asio event service, the central class of boost.asio.
Definition: util_fwd.hpp:135
boost::system::error_code Error_code
Short-hand for a boost.system error code (which basically encapsulates an integer/enum error code and...
Definition: common.hpp:503
Fine_clock::time_point Fine_time_pt
A high-res time point as returned by Fine_clock::now() and suitable for precise time math in general.
Definition: common.hpp:408
A set of low-level options affecting a single Peer_socket.
Definition: options.hpp:36