Flow 1.0.0
Flow project: Full implementation reference.
server_socket.cpp
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
20
22{
23
24// Implementations.
25
26// Server_socket implementations.
27
28Server_socket::Server_socket(log::Logger* logger_ptr, const Peer_socket_options* child_sock_opts) :
29 net_flow::Server_socket(logger_ptr, child_sock_opts),
30 m_target_task_engine(0)
31{
32 // Only print pointer value, because most members are garbage at this point.
33 FLOW_LOG_TRACE("boost.asio-integrated Server_socket [" << static_cast<void*>(this) << "] created; no Task_engine.");
34}
35
37{
38 FLOW_LOG_TRACE("boost.asio-integrated Server_socket [" << this << "] destroyed.");
39}
40
42{
43 // Not thread-safe against set_async_task_engine(). Discussed in my doc header.
45}
46
48{
49 return *m_target_task_engine; // Same comment as async_task_engine().
50}
51
53{
54 // Not thread-safe against m_target_task_engine access. Discussed in my doc header.
55 FLOW_LOG_INFO("Object [" << this << "] has been assigned an Task_engine at [" << target_async_task_engine << "]; "
56 "currently [" << static_cast<void*>(m_target_task_engine) << "].");
57 m_target_task_engine = target_async_task_engine;
58}
59
61 const Fine_time_pt& wait_until, bool reactor_pattern)
62{
63 // This is the actual async_accept() body, after the args have been converted into a convenient form.
64
65 // Need owner Node* to proceed.
66 assert(m_target_task_engine); // Note: cannot return civilized error, as nowhere to place error-receiving callback!
67 const auto owner_node = static_cast<Node*>(node());
68 if (!owner_node)
69 {
70 /* No Node* anymore => state is CLOSED, and reason why it was closed should be here. This is how we report
71 * attempts to do the non-blocking ops like accept() on CLOSED server sockets, and we are no different. */
72 const auto err_code = disconnect_cause();
73
74 FLOW_LOG_WARNING("Cannot perform async op on object [" << this << "]: it is already closed for "
75 "reason [" << err_code << '/' << err_code.message() << "].");
76 on_result(err_code, Peer_socket::Ptr()); // It post()s user's originally-passed-in handler.
77 return;
78 }
79 // else
80 assert(!on_result.empty()); // Feeble attempt to ensure on_result not blown away, because no error above.
81
82 const auto serv = cast(shared_from_this());
83
84 /* The wrapper function allows to reactor_pattern mode,
85 * wherein any actual I/O op is up to the handler on_result, and we just call it when ready.
86 * In particular no need to waste time on wrapping the non-blocking I/O op call, since we won't be
87 * doing it ourselves. */
88 Function<Peer_socket::Ptr (Error_code*)> non_blocking_func;
89 if (!reactor_pattern)
90 {
91 non_blocking_func = [serv](Error_code* err_code) -> Peer_socket::Ptr
92 {
93 return Peer_socket::cast(serv->accept(err_code));
94 };
95 }
96 // else { Leave it .empty() to indicate reactor_pattern. }
97
98 // Invoke this jack-of-all-trades, just supplying the op type-specific little pieces of the puzzle.
99 owner_node->async_op
101 (serv,
102 std::move(non_blocking_func),
104 std::move(on_result));
105}
106
108{
109 using boost::static_pointer_cast;
110 return static_pointer_cast<Server_socket>(serv);
111}
112
113// Node implementations (dealing with individual Server_sockets).
114
116{
117 // An asio::Node always creates asio::Server_socket (subclass) instances.
118 const auto serv = static_cast<Server_socket*>(serv_create_forward_plus_ctor_args<Server_socket>(child_sock_opts));
119
120 // As promised, propagate Node's service to created kid sockets (even if null). They can overwrite.
121 serv->set_async_task_engine(m_target_task_engine); // Thread-safe before we give out serv to others.
122
123 return static_cast<net_flow::Server_socket*>(serv);
124}
125
126// Free implementations.
127
128std::ostream& operator<<(std::ostream& os, const Server_socket* serv)
129{
130 return
131 serv
132 ? (os << "Asio_flow_server [Task_engine@" << static_cast<const void*>(&(serv->async_task_engine_cref())) << "] ["
133 << static_cast<const net_flow::Server_socket*>(serv) // Show underlying net_flow:: socket's details.
134 << "] @" << static_cast<const void*>(serv))
135 : (os << "Asio_flow_server@null");
136}
137
138} // namespace flow::net_flow::asio
Interface that the user should implement, passing the implementing Logger into logging classes (Flow'...
Definition: log.hpp:1291
@ S_SERVER_SOCKET_ACCEPTABLE
Event type specifying the condition of interest wherein a target Server_socket serv is such that call...
A server socket able to listen on a single Flow port for incoming connections and return peer sockets...
Error_code disconnect_cause() const
The error code that perviously caused state() to become State::S_CLOSED, or success code if state is ...
Node * node() const
Node that produced this Server_socket.
A subclass of net_flow::Node that adds the ability to easily and directly use net_flow sockets in gen...
Definition: node.hpp:236
util::Task_engine * m_target_task_engine
See async_task_engine().
Definition: node.hpp:575
net_flow::Server_socket * serv_create(const Peer_socket_options *child_sock_opts) override
Implements superclass API.
static Ptr cast(net_flow::Peer_socket::Ptr sock)
Convenience method that polymorphically casts from net_flow::Peer_socket::Ptr to subclass pointer net...
boost::shared_ptr< Peer_socket > Ptr
Short-hand for shared_ptr to Peer_socket.
Definition: peer_socket.hpp:46
A net_flow::Server_socket that adds integration with boost.asio.
void async_accept_impl(Handler_func &&on_result, const Fine_time_pt &wait_until, bool reactor_pattern)
De-templated implementation of all async_accept() methods.
Server_socket(log::Logger *logger, const Peer_socket_options *child_sock_opts)
Constructs object.
void set_async_task_engine(util::Task_engine *target_async_task_engine)
Overwrites the value to be returned by next async_task_engine().
~Server_socket() override
Boring virtual destructor as in superclass. See notes there.
const util::Task_engine & async_task_engine_cref() const
Read-only version of async_task_engine().
static Ptr cast(net_flow::Server_socket::Ptr serv)
Convenience method that polymorphically casts from net_flow::Server_socket::Ptr to subclass pointer n...
util::Task_engine * async_task_engine()
Pointer (possibly null) for the flow::util::Task_engine used by any coming async I/O calls and inheri...
boost::shared_ptr< Server_socket > Ptr
Short-hand for shared_ptr to Server_socket.
util::Task_engine * m_target_task_engine
See async_task_engine().
boost::shared_ptr< Server_socket > Ptr
Short-hand for ref-counted pointer to mutable values of type Target_type::element_type (a-la T*).
#define FLOW_LOG_INFO(ARG_stream_fragment)
Logs an INFO message into flow::log::Logger *get_logger() with flow::log::Component get_log_component...
Definition: log.hpp:197
#define FLOW_LOG_WARNING(ARG_stream_fragment)
Logs a WARNING message into flow::log::Logger *get_logger() with flow::log::Component get_log_compone...
Definition: log.hpp:152
#define FLOW_LOG_TRACE(ARG_stream_fragment)
Logs a TRACE message into flow::log::Logger *get_logger() with flow::log::Component get_log_component...
Definition: log.hpp:227
Contains classes that add boost.asio integration to the main Flow-protocol classes such as net_flow::...
Definition: node.cpp:25
std::ostream & operator<<(std::ostream &os, const Peer_socket *sock)
Prints string representation of given socket to given standard ostream and returns the latter.
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:502
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:407
A set of low-level options affecting a single Peer_socket.
Definition: options.hpp:36