src/corosio/src/tcp_socket.cpp

100.0% Lines (66/66) 100.0% List of functions (13/13) 78.1% Branches (25/32)
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 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/corosio
9 //
10
11 #include <boost/corosio/tcp_socket.hpp>
12 #include <boost/corosio/detail/except.hpp>
13 #include <boost/corosio/detail/platform.hpp>
14
15 #if BOOST_COROSIO_HAS_IOCP
16 #include <boost/corosio/native/detail/iocp/win_tcp_acceptor_service.hpp>
17 #else
18 #include <boost/corosio/detail/tcp_service.hpp>
19 #endif
20
21 namespace boost::corosio {
22
23 32001x tcp_socket::~tcp_socket()
24 32001x {
25 16044x close();
26 32001x }
27
28 26566x tcp_socket::tcp_socket(capy::execution_context& ctx)
29 #if BOOST_COROSIO_HAS_IOCP
30 : io_object(create_handle<detail::win_tcp_service>(ctx))
31 #else
32 13283x : io_object(create_handle<detail::tcp_service>(ctx))
33 #endif
34 26566x {
35 13283x }
36
37 std::error_code
38 6476x tcp_socket::open(tcp proto) noexcept
39 {
40
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6472 times.
6476x if (is_open())
41 4x return {};
42 6472x return open_for_family(proto.family(), proto.type(), proto.protocol());
43 6476x }
44
45 std::error_code
46 6472x tcp_socket::open_for_family(int family, int type, int protocol) noexcept
47 {
48 #if BOOST_COROSIO_HAS_IOCP
49 auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
50 auto& wrapper = static_cast<tcp_socket::implementation&>(*h_.get());
51 std::error_code ec = svc.open_socket(
52 *static_cast<detail::win_tcp_socket&>(wrapper).get_internal(), family,
53 type, protocol);
54 #else
55 6472x auto& svc = static_cast<detail::tcp_service&>(h_.service());
56
2/4
✓ Branch 0 taken 6472 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6472 times.
✗ Branch 3 not taken.
12944x std::error_code ec = svc.open_socket(
57 6472x static_cast<tcp_socket::implementation&>(*h_.get()), family, type,
58 6472x protocol);
59 #endif
60 6472x return ec;
61 }
62
63 std::error_code
64 24x tcp_socket::assign(native_handle_type fd) noexcept
65 {
66 #if BOOST_COROSIO_HAS_IOCP
67 auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
68 auto& wrapper = static_cast<tcp_socket::implementation&>(*h_.get());
69 std::error_code ec = svc.assign_socket(
70 *static_cast<detail::win_tcp_socket&>(wrapper).get_internal(), fd);
71 #else
72 24x auto& svc = static_cast<detail::tcp_service&>(h_.service());
73
2/4
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
48x std::error_code ec = svc.assign_socket(
74 24x static_cast<tcp_socket::implementation&>(*h_.get()), fd);
75 #endif
76 24x return ec;
77 }
78
79 native_handle_type
80 6x tcp_socket::release()
81 {
82
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6x if (!is_open())
83 2x detail::throw_system_error(
84 2x make_error_code(std::errc::bad_file_descriptor),
85 "tcp_socket::release");
86 4x return get().release_socket();
87 }
88
89 std::error_code
90 18x tcp_socket::bind(endpoint ep) noexcept
91 {
92
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18x if (!is_open())
93 2x return make_error_code(std::errc::bad_file_descriptor);
94 #if BOOST_COROSIO_HAS_IOCP
95 auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
96 auto& wrapper = static_cast<tcp_socket::implementation&>(*h_.get());
97 return svc.bind_socket(
98 *static_cast<detail::win_tcp_socket&>(wrapper).get_internal(), ep);
99 #else
100 16x auto& svc = static_cast<detail::tcp_service&>(h_.service());
101
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
32x return svc.bind_socket(
102 16x static_cast<tcp_socket::implementation&>(*h_.get()), ep);
103 #endif
104 18x }
105
106 void
107 29160x tcp_socket::close() noexcept
108 {
109
2/2
✓ Branch 0 taken 12805 times.
✓ Branch 1 taken 16355 times.
29160x if (!is_open())
110 16355x return;
111
1/2
✓ Branch 0 taken 12805 times.
✗ Branch 1 not taken.
12805x h_.service().close(h_);
112 29160x }
113
114 void
115 222x tcp_socket::cancel() noexcept
116 {
117
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 220 times.
222x if (!is_open())
118 2x return;
119 220x get().cancel();
120 222x }
121
122 std::error_code
123 28x tcp_socket::shutdown(shutdown_type what) noexcept
124 {
125
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 22 times.
28x if (!is_open())
126 6x return make_error_code(std::errc::bad_file_descriptor);
127 22x return get().shutdown(what);
128 28x }
129
130 native_handle_type
131 64x tcp_socket::native_handle() const noexcept
132 {
133
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 62 times.
64x if (!is_open())
134 {
135 #if BOOST_COROSIO_HAS_IOCP
136 return static_cast<native_handle_type>(~0ull); // INVALID_SOCKET
137 #else
138 2x return -1;
139 #endif
140 }
141 62x return get().native_handle();
142 64x }
143
144 endpoint
145 68x tcp_socket::local_endpoint() const noexcept
146 {
147
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 58 times.
68x if (!is_open())
148 10x return endpoint{};
149 58x return get().local_endpoint();
150 68x }
151
152 endpoint
153 68x tcp_socket::remote_endpoint() const noexcept
154 {
155
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 58 times.
68x if (!is_open())
156 10x return endpoint{};
157 58x return get().remote_endpoint();
158 68x }
159
160 } // namespace boost::corosio
161