src/corosio/src/tcp_socket.cpp

100.0% Lines (62/62) 100.0% List of functions (13/13) 100.0% Branches (22/22)
tcp_socket.cpp
f(x) Functions (13)
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco ([email protected])
3 // Copyright (c) 2026 Steve Gerbino
4 // Copyright (c) 2026 Michael Vandeberg
5 //
6 // Distributed under the Boost Software License, Version 1.0. (See accompanying
7 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // Official repository: https://github.com/cppalliance/corosio
10 //
11
12 #include <boost/corosio/tcp_socket.hpp>
13 #include <boost/corosio/error.hpp>
14 #include <boost/corosio/native/detail/endpoint_convert.hpp>
15 #include <boost/corosio/detail/except.hpp>
16 #include <boost/corosio/detail/platform.hpp>
17
18 #include "src/detail/use_backend_service.hpp"
19
20 #if BOOST_COROSIO_HAS_IOCP
21 #include <boost/corosio/native/detail/iocp/win_tcp_acceptor_service.hpp>
22 #else
23 #include <boost/corosio/detail/tcp_service.hpp>
24 #endif
25
26 namespace boost::corosio {
27
28 namespace {
29
30 #if BOOST_COROSIO_HAS_IOCP
31 using tcp_service_key = detail::win_tcp_service;
32 #else
33 using tcp_service_key = detail::tcp_service;
34 #endif
35
36 } // namespace
37
38 7559x tcp_socket::~tcp_socket()
39 {
40 7551x close();
41 7559x }
42
43 4111x tcp_socket::tcp_socket(capy::execution_context& ctx)
44 4111x : io_object(handle(
45 ctx,
46 8222x detail::use_backend_service<detail::tcp_service_of, tcp_service_key>(
47
2/2
✓ Branch 2 → 3 taken 4111 times.
✓ Branch 3 → 4 taken 4111 times.
8222x ctx)))
48 {
49 4111x }
50
51 std::error_code
52 1883x tcp_socket::open(family f) noexcept
53 {
54
2/2
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 5 taken 1881 times.
1883x if (is_open())
55 2x return {};
56 1881x return open_for_family(detail::native_family(f), SOCK_STREAM, IPPROTO_TCP);
57 }
58
59 std::error_code
60 1881x tcp_socket::open_for_family(int family, int type, int protocol) noexcept
61 {
62 #if BOOST_COROSIO_HAS_IOCP
63 1881x auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
64 1881x auto& wrapper = static_cast<tcp_socket::implementation&>(*h_.get());
65 1881x std::error_code ec = svc.open_socket(
66 1881x *static_cast<detail::win_tcp_socket&>(wrapper).get_internal(), family,
67 type, protocol);
68 #else
69 auto& svc = static_cast<detail::tcp_service&>(h_.service());
70 std::error_code ec = svc.open_socket(
71 static_cast<tcp_socket::implementation&>(*h_.get()), family, type,
72 protocol);
73 #endif
74 1881x return ec;
75 }
76
77 std::error_code
78 30x tcp_socket::assign(native_handle_type fd) noexcept
79 {
80
2/2
✓ Branch 3 → 4 taken 5 times.
✓ Branch 3 → 5 taken 25 times.
30x if (is_open())
81 5x return make_error_code(error::already_open);
82 #if BOOST_COROSIO_HAS_IOCP
83 25x auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
84 25x auto& wrapper = static_cast<tcp_socket::implementation&>(*h_.get());
85 25x std::error_code ec = svc.assign_socket(
86 25x *static_cast<detail::win_tcp_socket&>(wrapper).get_internal(), fd);
87 #else
88 auto& svc = static_cast<detail::tcp_service&>(h_.service());
89 std::error_code ec = svc.assign_socket(
90 static_cast<tcp_socket::implementation&>(*h_.get()), fd);
91 #endif
92 25x return ec;
93 }
94
95 native_handle_type
96 6x tcp_socket::release()
97 {
98
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 6 taken 5 times.
6x if (!is_open())
99 1x detail::throw_system_error(
100 1x make_error_code(std::errc::bad_file_descriptor),
101 "tcp_socket::release");
102 5x return get().release_socket();
103 }
104
105 std::error_code
106 9x tcp_socket::bind(endpoint ep) noexcept
107 {
108
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 8 times.
9x if (!is_open())
109 1x return make_error_code(std::errc::bad_file_descriptor);
110 #if BOOST_COROSIO_HAS_IOCP
111 8x auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
112 8x auto& wrapper = static_cast<tcp_socket::implementation&>(*h_.get());
113 8x return svc.bind_socket(
114 16x *static_cast<detail::win_tcp_socket&>(wrapper).get_internal(), ep);
115 #else
116 auto& svc = static_cast<detail::tcp_service&>(h_.service());
117 return svc.bind_socket(
118 static_cast<tcp_socket::implementation&>(*h_.get()), ep);
119 #endif
120 }
121
122 void
123 11760x tcp_socket::close() noexcept
124 {
125
2/2
✓ Branch 3 → 4 taken 8089 times.
✓ Branch 3 → 5 taken 3671 times.
11760x if (!is_open())
126 8089x return;
127 3671x h_.service().close(h_);
128 }
129
130 void
131 2185x tcp_socket::cancel() noexcept
132 {
133
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 2184 times.
2185x if (!is_open())
134 1x return;
135 2184x get().cancel();
136 }
137
138 std::error_code
139 17x tcp_socket::shutdown(shutdown_type what) noexcept
140 {
141
2/2
✓ Branch 3 → 4 taken 3 times.
✓ Branch 3 → 5 taken 14 times.
17x if (!is_open())
142 3x return make_error_code(std::errc::bad_file_descriptor);
143 14x return get().shutdown(what);
144 }
145
146 native_handle_type
147 29x tcp_socket::native_handle() const noexcept
148 {
149
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 28 times.
29x if (!is_open())
150 {
151 #if BOOST_COROSIO_HAS_IOCP
152 1x return static_cast<native_handle_type>(~0ull); // INVALID_SOCKET
153 #else
154 return -1;
155 #endif
156 }
157 28x return get().native_handle();
158 }
159
160 endpoint
161 34x tcp_socket::local_endpoint() const noexcept
162 {
163
2/2
✓ Branch 3 → 4 taken 5 times.
✓ Branch 3 → 5 taken 29 times.
34x if (!is_open())
164 5x return endpoint{};
165 29x return get().local_endpoint();
166 }
167
168 endpoint
169 34x tcp_socket::remote_endpoint() const noexcept
170 {
171
2/2
✓ Branch 3 → 4 taken 5 times.
✓ Branch 3 → 5 taken 29 times.
34x if (!is_open())
172 5x return endpoint{};
173 29x return get().remote_endpoint();
174 }
175
176 } // namespace boost::corosio
177