include/boost/corosio/native/detail/reactor/reactor_stream_socket.hpp

85.0% Lines (175/206) 81.6% List of functions (31/38) 43.6% Branches (122/280)
reactor_stream_socket.hpp
f(x) Functions (38)
Function Calls Lines Branches Blocks
boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::reactor_stream_socket(boost::corosio::detail::kqueue_tcp_service&) :61 16035x 100.0% 100.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::reactor_stream_socket(boost::corosio::detail::select_tcp_service&) :61 5247x 0.0% 100.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::~reactor_stream_socket() :76 16035x 100.0% 100.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::~reactor_stream_socket() :76 5247x 0.0% 100.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::remote_endpoint() const :79 22x 100.0% 100.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::remote_endpoint() const :79 22x 0.0% 100.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::shutdown(boost::corosio::tcp_socket::shutdown_type) :85 3x 84.6% 50.0% 66.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::shutdown(boost::corosio::tcp_socket::shutdown_type) :85 3x 0.0% 0.0% 66.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::set_endpoints(boost::corosio::endpoint, boost::corosio::endpoint) :108 10614x 100.0% 100.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::set_endpoints(boost::corosio::endpoint, boost::corosio::endpoint) :108 3474x 0.0% 100.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::do_close_socket() :160 48039x 100.0% 100.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::do_close_socket() :160 15753x 100.0% 100.0% boost::corosio::detail::reactor_op_base** boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::op_to_desc_slot<boost::corosio::detail::kqueue_connect_op>(boost::corosio::detail::kqueue_connect_op&) :170 0 100.0% 0.0% boost::corosio::detail::reactor_op_base** boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::op_to_desc_slot<boost::corosio::detail::kqueue_read_op>(boost::corosio::detail::kqueue_read_op&) :170 656x 100.0% 50.0% boost::corosio::detail::reactor_op_base** boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::op_to_desc_slot<boost::corosio::detail::kqueue_write_op>(boost::corosio::detail::kqueue_write_op&) :170 1x 77.8% 19.4% 62.0% boost::corosio::detail::reactor_op_base** boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::op_to_desc_slot<boost::corosio::detail::select_connect_op>(boost::corosio::detail::select_connect_op&) :170 0 100.0% 0.0% boost::corosio::detail::reactor_op_base** boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::op_to_desc_slot<boost::corosio::detail::select_read_op>(boost::corosio::detail::select_read_op&) :170 30x 100.0% 50.0% boost::corosio::detail::reactor_op_base** boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::op_to_desc_slot<boost::corosio::detail::select_write_op>(boost::corosio::detail::select_write_op&) :170 0 0.0% 0.0% 0.0% bool* boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::op_to_cancel_flag<boost::corosio::detail::kqueue_connect_op>(boost::corosio::detail::kqueue_connect_op&) :182 0 100.0% 0.0% bool* boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::op_to_cancel_flag<boost::corosio::detail::kqueue_read_op>(boost::corosio::detail::kqueue_read_op&) :182 1x 100.0% 50.0% bool* boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::op_to_cancel_flag<boost::corosio::detail::kqueue_write_op>(boost::corosio::detail::kqueue_write_op&) :182 1x 77.8% 13.9% 62.0% bool* boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::op_to_cancel_flag<boost::corosio::detail::select_connect_op>(boost::corosio::detail::select_connect_op&) :182 0 100.0% 0.0% bool* boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::op_to_cancel_flag<boost::corosio::detail::select_read_op>(boost::corosio::detail::select_read_op&) :182 0 100.0% 0.0% bool* boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::op_to_cancel_flag<boost::corosio::detail::select_write_op>(boost::corosio::detail::select_write_op&) :182 0 0.0% 0.0% 0.0% void boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::for_each_op<boost::corosio::detail::reactor_basic_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::descriptor_state>::do_cancel()::'lambda'(auto&)>(auto) :194 117x 100.0% 37.5% 80.0% void boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::for_each_op<boost::corosio::detail::reactor_basic_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::descriptor_state>::do_close_socket()::'lambda'(auto&)>(auto) :194 48039x 100.0% 80.0% void boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::for_each_op<boost::corosio::detail::reactor_basic_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_descriptor_state>::do_cancel()::'lambda'(auto&)>(auto) :194 42x 0.0% 0.0% 80.0% void boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::for_each_op<boost::corosio::detail::reactor_basic_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_descriptor_state>::do_close_socket()::'lambda'(auto&)>(auto) :194 15753x 100.0% 80.0% void boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::for_each_desc_entry<boost::corosio::detail::reactor_basic_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::descriptor_state>::do_cancel()::'lambda'(auto&, boost::corosio::detail::reactor_op_base*&)>(auto) :202 117x 100.0% 37.5% 80.0% void boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::for_each_desc_entry<boost::corosio::detail::reactor_basic_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::descriptor_state>::do_close_socket()::'lambda'(auto&, boost::corosio::detail::reactor_op_base*&)>(auto) :202 48039x 100.0% 80.0% void boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::for_each_desc_entry<boost::corosio::detail::reactor_basic_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_descriptor_state>::do_cancel()::'lambda'(auto&, boost::corosio::detail::reactor_op_base*&)>(auto) :202 42x 0.0% 0.0% 80.0% void boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::for_each_desc_entry<boost::corosio::detail::reactor_basic_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_descriptor_state>::do_close_socket()::'lambda'(auto&, boost::corosio::detail::reactor_op_base*&)>(auto) :202 15753x 100.0% 80.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::do_connect(std::__1::coroutine_handle<void>, boost::capy::executor_ref, boost::corosio::endpoint, std::__1::stop_token const&, std::__1::error_code*) :219 5309x 46.7% 18.8% 29.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::do_connect(std::__1::coroutine_handle<void>, boost::capy::executor_ref, boost::corosio::endpoint, std::__1::stop_token const&, std::__1::error_code*) :219 1739x 0.0% 0.0% 29.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::do_read_some(std::__1::coroutine_handle<void>, boost::capy::executor_ref, boost::corosio::buffer_param, std::__1::stop_token const&, std::__1::error_code*, unsigned long*) :291 386255x 98.2% 68.8% 81.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::do_read_some(std::__1::coroutine_handle<void>, boost::capy::executor_ref, boost::corosio::buffer_param, std::__1::stop_token const&, std::__1::error_code*, unsigned long*) :291 444210x 0.0% 0.0% 81.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::kqueue_tcp_socket, boost::corosio::detail::kqueue_tcp_service, boost::corosio::detail::kqueue_connect_op, boost::corosio::detail::kqueue_read_op, boost::corosio::detail::kqueue_write_op, boost::corosio::detail::descriptor_state>::do_write_some(std::__1::coroutine_handle<void>, boost::capy::executor_ref, boost::corosio::buffer_param, std::__1::stop_token const&, std::__1::error_code*, unsigned long*) :385 484200x 100.0% 72.7% 92.0% boost::corosio::detail::reactor_stream_socket<boost::corosio::detail::select_tcp_socket, boost::corosio::detail::select_tcp_service, boost::corosio::detail::select_connect_op, boost::corosio::detail::select_read_op, boost::corosio::detail::select_write_op, boost::corosio::detail::select_descriptor_state>::do_write_some(std::__1::coroutine_handle<void>, boost::capy::executor_ref, boost::corosio::buffer_param, std::__1::stop_token const&, std::__1::error_code*, unsigned long*) :385 445570x 0.0% 0.0% 82.0%
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Steve Gerbino
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #ifndef BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_STREAM_SOCKET_HPP
11 #define BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_STREAM_SOCKET_HPP
12
13 #include <boost/corosio/tcp_socket.hpp>
14 #include <boost/corosio/native/detail/reactor/reactor_basic_socket.hpp>
15 #include <boost/corosio/detail/dispatch_coro.hpp>
16 #include <boost/capy/buffers.hpp>
17
18 #include <coroutine>
19
20 #include <errno.h>
21 #include <sys/socket.h>
22 #include <sys/uio.h>
23
24 namespace boost::corosio::detail {
25
26 /** CRTP base for reactor-backed stream socket implementations.
27
28 Inherits shared data members and cancel/close/register logic
29 from reactor_basic_socket. Adds the TCP-specific remote
30 endpoint, shutdown, and I/O dispatch (connect, read, write).
31
32 @tparam Derived The concrete socket type (CRTP).
33 @tparam Service The backend's socket service type.
34 @tparam ConnOp The backend's connect op type.
35 @tparam ReadOp The backend's read op type.
36 @tparam WriteOp The backend's write op type.
37 @tparam DescState The backend's descriptor_state type.
38 */
39 template<
40 class Derived,
41 class Service,
42 class ConnOp,
43 class ReadOp,
44 class WriteOp,
45 class DescState>
46 class reactor_stream_socket
47 : public reactor_basic_socket<
48 Derived,
49 tcp_socket::implementation,
50 Service,
51 DescState>
52 {
53 using base_type = reactor_basic_socket<
54 Derived,
55 tcp_socket::implementation,
56 Service,
57 DescState>;
58 friend base_type;
59 friend Derived;
60
61 21282x explicit reactor_stream_socket(Service& svc) noexcept : base_type(svc) {}
62
63 protected:
64 endpoint remote_endpoint_;
65
66 public:
67 /// Pending connect operation slot.
68 ConnOp conn_;
69
70 /// Pending read operation slot.
71 ReadOp rd_;
72
73 /// Pending write operation slot.
74 WriteOp wr_;
75
76 21282x ~reactor_stream_socket() override = default;
77
78 /// Return the cached remote endpoint.
79 44x endpoint remote_endpoint() const noexcept override
80 {
81 44x return remote_endpoint_;
82 }
83
84 /// Shut down part or all of the full-duplex connection.
85 6x std::error_code shutdown(tcp_socket::shutdown_type what) noexcept override
86 {
87 int how;
88
6/8
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✓ Branch 7 taken 1 time.
6x switch (what)
89 {
90 case tcp_socket::shutdown_receive:
91 2x how = SHUT_RD;
92 2x break;
93 case tcp_socket::shutdown_send:
94 2x how = SHUT_WR;
95 2x break;
96 case tcp_socket::shutdown_both:
97 2x how = SHUT_RDWR;
98 2x break;
99 default:
100 return make_err(EINVAL);
101 }
102
4/8
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
6x if (::shutdown(this->fd_, how) != 0)
103 return make_err(errno);
104 6x return {};
105 6x }
106
107 /// Cache local and remote endpoints.
108 14088x void set_endpoints(endpoint local, endpoint remote) noexcept
109 {
110 14088x this->local_endpoint_ = local;
111 14088x remote_endpoint_ = remote;
112 14088x }
113
114 /** Shared connect dispatch.
115
116 Tries the connect syscall speculatively. On synchronous
117 completion, returns via inline budget or posts through queue.
118 On EINPROGRESS, registers with the reactor.
119 */
120 std::coroutine_handle<> do_connect(
121 std::coroutine_handle<>,
122 capy::executor_ref,
123 endpoint,
124 std::stop_token const&,
125 std::error_code*);
126
127 /** Shared scatter-read dispatch.
128
129 Tries readv() speculatively. On success or hard error,
130 returns via inline budget or posts through queue.
131 On EAGAIN, registers with the reactor.
132 */
133 std::coroutine_handle<> do_read_some(
134 std::coroutine_handle<>,
135 capy::executor_ref,
136 buffer_param,
137 std::stop_token const&,
138 std::error_code*,
139 std::size_t*);
140
141 /** Shared gather-write dispatch.
142
143 Tries the write via WriteOp::write_policy speculatively.
144 On success or hard error, returns via inline budget or
145 posts through queue. On EAGAIN, registers with the reactor.
146 */
147 std::coroutine_handle<> do_write_some(
148 std::coroutine_handle<>,
149 capy::executor_ref,
150 buffer_param,
151 std::stop_token const&,
152 std::error_code*,
153 std::size_t*);
154
155 /** Close the socket and cancel pending operations.
156
157 Extends the base do_close_socket() to also reset
158 the remote endpoint.
159 */
160 63792x void do_close_socket() noexcept
161 {
162 63792x base_type::do_close_socket();
163 63792x remote_endpoint_ = endpoint{};
164 63792x }
165
166 private:
167 // CRTP callbacks for reactor_basic_socket cancel/close
168
169 template<class Op>
170 687x reactor_op_base** op_to_desc_slot(Op& op) noexcept
171 {
172
3/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 656 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
✗ Branch 11 not taken.
687x if (&op == static_cast<void*>(&conn_))
173 return &this->desc_state_.connect_op;
174
3/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 656 times.
✓ Branch 10 taken 1 time.
✗ Branch 11 not taken.
687x if (&op == static_cast<void*>(&rd_))
175 686x return &this->desc_state_.read_op;
176
1/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 time.
1x if (&op == static_cast<void*>(&wr_))
177 1x return &this->desc_state_.write_op;
178 return nullptr;
179 687x }
180
181 template<class Op>
182 2x bool* op_to_cancel_flag(Op& op) noexcept
183 {
184
2/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
✗ Branch 11 not taken.
2x if (&op == static_cast<void*>(&conn_))
185 return &this->desc_state_.connect_cancel_pending;
186
2/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✓ Branch 10 taken 1 time.
✗ Branch 11 not taken.
2x if (&op == static_cast<void*>(&rd_))
187 1x return &this->desc_state_.read_cancel_pending;
188
1/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 time.
1x if (&op == static_cast<void*>(&wr_))
189 1x return &this->desc_state_.write_cancel_pending;
190 return nullptr;
191 2x }
192
193 template<class Fn>
194 63951x void for_each_op(Fn fn) noexcept
195 {
196
3/8
✓ Branch 0 taken 15795 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48039 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
63951x fn(conn_);
197
3/8
✓ Branch 0 taken 15795 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48039 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
63951x fn(rd_);
198
3/8
✓ Branch 0 taken 15795 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48039 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
63951x fn(wr_);
199 63951x }
200
201 template<class Fn>
202 63951x void for_each_desc_entry(Fn fn) noexcept
203 {
204
3/8
✓ Branch 0 taken 15795 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48039 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
63951x fn(conn_, this->desc_state_.connect_op);
205
3/8
✓ Branch 0 taken 15795 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48039 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
63951x fn(rd_, this->desc_state_.read_op);
206
3/8
✓ Branch 0 taken 15795 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48039 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
63951x fn(wr_, this->desc_state_.write_op);
207 63951x }
208 };
209
210 template<
211 class Derived,
212 class Service,
213 class ConnOp,
214 class ReadOp,
215 class WriteOp,
216 class DescState>
217 std::coroutine_handle<>
218 reactor_stream_socket<Derived, Service, ConnOp, ReadOp, WriteOp, DescState>::
219 7048x do_connect(
220 std::coroutine_handle<> h,
221 capy::executor_ref ex,
222 endpoint ep,
223 std::stop_token const& token,
224 std::error_code* ec)
225 {
226 7048x auto& op = conn_;
227
228 7048x sockaddr_storage storage{};
229 7048x socklen_t addrlen = to_sockaddr(ep, socket_family(this->fd_), storage);
230 7048x int result =
231 7048x ::connect(this->fd_, reinterpret_cast<sockaddr*>(&storage), addrlen);
232
233
2/4
✓ Branch 0 taken 1739 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5309 times.
✗ Branch 3 not taken.
7048x if (result == 0)
234 {
235 sockaddr_storage local_storage{};
236 socklen_t local_len = sizeof(local_storage);
237 if (::getsockname(
238 this->fd_, reinterpret_cast<sockaddr*>(&local_storage),
239 &local_len) == 0)
240 this->local_endpoint_ = from_sockaddr(local_storage);
241 remote_endpoint_ = ep;
242 }
243
244
4/8
✓ Branch 0 taken 1739 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1739 times.
✓ Branch 4 taken 5309 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 5309 times.
7048x if (result == 0 || errno != EINPROGRESS)
245 {
246 int err = (result < 0) ? errno : 0;
247 if (this->svc_.scheduler().try_consume_inline_budget())
248 {
249 *ec = err ? make_err(err) : std::error_code{};
250 op.cont_op.cont.h = h;
251 return dispatch_coro(ex, op.cont_op.cont);
252 }
253 op.reset();
254 op.h = h;
255 op.ex = ex;
256 op.ec_out = ec;
257 op.fd = this->fd_;
258 op.target_endpoint = ep;
259 op.start(token, static_cast<Derived*>(this));
260 op.impl_ptr = this->shared_from_this();
261 op.complete(err, 0);
262 this->svc_.post(&op);
263 return std::noop_coroutine();
264 }
265
266 // EINPROGRESS — register with reactor
267 7048x op.reset();
268 7048x op.h = h;
269 7048x op.ex = ex;
270 7048x op.ec_out = ec;
271 7048x op.fd = this->fd_;
272 7048x op.target_endpoint = ep;
273 7048x op.start(token, static_cast<Derived*>(this));
274 7048x op.impl_ptr = this->shared_from_this();
275
276 7048x this->register_op(
277 7048x op, this->desc_state_.connect_op, this->desc_state_.write_ready,
278 7048x this->desc_state_.connect_cancel_pending);
279 7048x return std::noop_coroutine();
280 7048x }
281
282 template<
283 class Derived,
284 class Service,
285 class ConnOp,
286 class ReadOp,
287 class WriteOp,
288 class DescState>
289 std::coroutine_handle<>
290 reactor_stream_socket<Derived, Service, ConnOp, ReadOp, WriteOp, DescState>::
291 830465x do_read_some(
292 std::coroutine_handle<> h,
293 capy::executor_ref ex,
294 buffer_param param,
295 std::stop_token const& token,
296 std::error_code* ec,
297 std::size_t* bytes_out)
298 {
299 830465x auto& op = rd_;
300 830465x op.reset();
301
302 830465x capy::mutable_buffer bufs[ReadOp::max_buffers];
303 830465x op.iovec_count = static_cast<int>(param.copy_to(bufs, ReadOp::max_buffers));
304
305
8/12
✓ Branch 0 taken 444209 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 444209 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 444209 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 386254 times.
✓ Branch 7 taken 1 time.
✓ Branch 8 taken 386254 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 386254 times.
✗ Branch 11 not taken.
830465x if (op.iovec_count == 0 || (op.iovec_count == 1 && bufs[0].size() == 0))
306 {
307 2x op.empty_buffer_read = true;
308 2x op.h = h;
309 2x op.ex = ex;
310 2x op.ec_out = ec;
311 2x op.bytes_out = bytes_out;
312 2x op.start(token, static_cast<Derived*>(this));
313
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
2x op.impl_ptr = this->shared_from_this();
314 2x op.complete(0, 0);
315 2x this->svc_.post(&op);
316 2x return std::noop_coroutine();
317 }
318
319
4/4
✓ Branch 0 taken 444209 times.
✓ Branch 1 taken 444209 times.
✓ Branch 2 taken 386254 times.
✓ Branch 3 taken 386254 times.
1660926x for (int i = 0; i < op.iovec_count; ++i)
320 {
321 830463x op.iovecs[i].iov_base = bufs[i].data();
322 830463x op.iovecs[i].iov_len = bufs[i].size();
323 830463x }
324
325 // Speculative read
326 ssize_t n;
327 830463x do
328 {
329 830463x n = ::readv(this->fd_, op.iovecs, op.iovec_count);
330 1660926x }
331
4/4
✓ Branch 0 taken 396297 times.
✓ Branch 1 taken 47912 times.
✓ Branch 2 taken 322765 times.
✓ Branch 3 taken 63489 times.
830463x while (n < 0 && errno == EINTR);
332
333
6/12
✓ Branch 0 taken 47912 times.
✓ Branch 1 taken 396297 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 47912 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 63489 times.
✓ Branch 7 taken 322765 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 63489 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
830463x if (n >= 0 || (errno != EAGAIN && errno != EWOULDBLOCK))
334 {
335
2/4
✓ Branch 0 taken 396297 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 322765 times.
✗ Branch 3 not taken.
719062x int err = (n < 0) ? errno : 0;
336
4/4
✓ Branch 0 taken 396292 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 322759 times.
✓ Branch 3 taken 6 times.
719062x auto bytes = (n > 0) ? static_cast<std::size_t>(n) : std::size_t(0);
337
338
4/4
✓ Branch 0 taken 320411 times.
✓ Branch 1 taken 75886 times.
✓ Branch 2 taken 260100 times.
✓ Branch 3 taken 62665 times.
719062x if (this->svc_.scheduler().try_consume_inline_budget())
339 {
340
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 320411 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 260100 times.
580511x if (err)
341 *ec = make_err(err);
342
4/4
✓ Branch 0 taken 320406 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 260094 times.
✓ Branch 3 taken 6 times.
580511x else if (n == 0)
343 11x *ec = capy::error::eof;
344 else
345 580500x *ec = {};
346 580511x *bytes_out = bytes;
347 580511x op.cont_op.cont.h = h;
348 580511x return dispatch_coro(ex, op.cont_op.cont);
349 }
350 138551x op.h = h;
351 138551x op.ex = ex;
352 138551x op.ec_out = ec;
353 138551x op.bytes_out = bytes_out;
354 138551x op.start(token, static_cast<Derived*>(this));
355
2/4
✓ Branch 0 taken 75886 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62665 times.
✗ Branch 3 not taken.
138551x op.impl_ptr = this->shared_from_this();
356 138551x op.complete(err, bytes);
357 138551x this->svc_.post(&op);
358 138551x return std::noop_coroutine();
359 }
360
361 // EAGAIN — register with reactor
362 111401x op.h = h;
363 111401x op.ex = ex;
364 111401x op.ec_out = ec;
365 111401x op.bytes_out = bytes_out;
366 111401x op.fd = this->fd_;
367 111401x op.start(token, static_cast<Derived*>(this));
368
2/4
✓ Branch 0 taken 47912 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 63489 times.
✗ Branch 3 not taken.
111401x op.impl_ptr = this->shared_from_this();
369
370 111401x this->register_op(
371 111401x op, this->desc_state_.read_op, this->desc_state_.read_ready,
372 111401x this->desc_state_.read_cancel_pending);
373 111401x return std::noop_coroutine();
374 830465x }
375
376 template<
377 class Derived,
378 class Service,
379 class ConnOp,
380 class ReadOp,
381 class WriteOp,
382 class DescState>
383 std::coroutine_handle<>
384 reactor_stream_socket<Derived, Service, ConnOp, ReadOp, WriteOp, DescState>::
385 929770x do_write_some(
386 std::coroutine_handle<> h,
387 capy::executor_ref ex,
388 buffer_param param,
389 std::stop_token const& token,
390 std::error_code* ec,
391 std::size_t* bytes_out)
392 {
393 929770x auto& op = wr_;
394 929770x op.reset();
395
396 929770x capy::mutable_buffer bufs[WriteOp::max_buffers];
397 929770x op.iovec_count =
398 929770x static_cast<int>(param.copy_to(bufs, WriteOp::max_buffers));
399
400
8/12
✓ Branch 0 taken 445569 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 445569 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 445569 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 484199 times.
✓ Branch 7 taken 1 time.
✓ Branch 8 taken 484199 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 484199 times.
✗ Branch 11 not taken.
929770x if (op.iovec_count == 0 || (op.iovec_count == 1 && bufs[0].size() == 0))
401 {
402 2x op.h = h;
403 2x op.ex = ex;
404 2x op.ec_out = ec;
405 2x op.bytes_out = bytes_out;
406 2x op.start(token, static_cast<Derived*>(this));
407 2x op.impl_ptr = this->shared_from_this();
408 2x op.complete(0, 0);
409 2x this->svc_.post(&op);
410 2x return std::noop_coroutine();
411 }
412
413
4/4
✓ Branch 0 taken 445569 times.
✓ Branch 1 taken 445569 times.
✓ Branch 2 taken 484199 times.
✓ Branch 3 taken 484199 times.
1859536x for (int i = 0; i < op.iovec_count; ++i)
414 {
415 929768x op.iovecs[i].iov_base = bufs[i].data();
416 929768x op.iovecs[i].iov_len = bufs[i].size();
417 929768x }
418
419 // Speculative write via backend-specific write policy
420 929768x ssize_t n =
421 929768x WriteOp::write_policy::write(this->fd_, op.iovecs, op.iovec_count);
422
423
7/12
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 445568 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✓ Branch 7 taken 484198 times.
✓ Branch 8 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
✗ Branch 11 not taken.
929768x if (n >= 0 || (errno != EAGAIN && errno != EWOULDBLOCK))
424 {
425
3/4
✓ Branch 0 taken 445568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 484198 times.
✓ Branch 3 taken 1 time.
929767x int err = (n < 0) ? errno : 0;
426
3/4
✓ Branch 0 taken 445568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 484198 times.
✓ Branch 3 taken 1 time.
929767x auto bytes = (n > 0) ? static_cast<std::size_t>(n) : std::size_t(0);
427
428
4/4
✓ Branch 0 taken 365413 times.
✓ Branch 1 taken 80155 times.
✓ Branch 2 taken 396564 times.
✓ Branch 3 taken 87635 times.
929767x if (this->svc_.scheduler().try_consume_inline_budget())
429 {
430
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 365413 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 396563 times.
761977x *ec = err ? make_err(err) : std::error_code{};
431 761977x *bytes_out = bytes;
432 761977x op.cont_op.cont.h = h;
433 761977x return dispatch_coro(ex, op.cont_op.cont);
434 }
435 167790x op.h = h;
436 167790x op.ex = ex;
437 167790x op.ec_out = ec;
438 167790x op.bytes_out = bytes_out;
439 167790x op.start(token, static_cast<Derived*>(this));
440 167790x op.impl_ptr = this->shared_from_this();
441 167790x op.complete(err, bytes);
442 167790x this->svc_.post(&op);
443 167790x return std::noop_coroutine();
444 }
445
446 // EAGAIN — register with reactor
447 1x op.h = h;
448 1x op.ex = ex;
449 1x op.ec_out = ec;
450 1x op.bytes_out = bytes_out;
451 1x op.fd = this->fd_;
452 1x op.start(token, static_cast<Derived*>(this));
453 1x op.impl_ptr = this->shared_from_this();
454
455 1x this->register_op(
456 1x op, this->desc_state_.write_op, this->desc_state_.write_ready,
457 1x this->desc_state_.write_cancel_pending);
458 1x return std::noop_coroutine();
459 929770x }
460
461 } // namespace boost::corosio::detail
462
463 #endif // BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_STREAM_SOCKET_HPP
464