src/corosio/src/tcp_socket.cpp

98.2% Lines (56/57) 100.0% List of functions (11/11) 90.0% Branches (18/20)
tcp_socket.cpp
f(x) Functions (11)
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 36448x tcp_socket::~tcp_socket()
24 36448x {
25
1/2
✓ Branch 0 taken 18254 times.
✗ Branch 1 not taken.
18254x close();
26 36448x }
27
28 31860x 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 15930x : io_object(create_handle<detail::tcp_service>(ctx))
33 #endif
34 31860x {
35 15930x }
36
37 void
38 7933x tcp_socket::open(tcp proto)
39 {
40
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7931 times.
7933x if (is_open())
41 2x return;
42 7931x open_for_family(proto.family(), proto.type(), proto.protocol());
43 7933x }
44
45 void
46 7931x tcp_socket::open_for_family(int family, int type, int protocol)
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, type,
53 protocol);
54 #else
55 7931x auto& svc = static_cast<detail::tcp_service&>(h_.service());
56 15862x std::error_code ec = svc.open_socket(
57 7931x static_cast<tcp_socket::implementation&>(*h_.get()), family, type,
58 7931x protocol);
59 #endif
60
1/2
✓ Branch 0 taken 7931 times.
✗ Branch 1 not taken.
7931x if (ec)
61 detail::throw_system_error(ec, "tcp_socket::open");
62 7931x }
63
64 std::error_code
65 16x tcp_socket::bind(endpoint ep)
66 {
67
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16x if (!is_open())
68 2x detail::throw_logic_error("bind: socket not open");
69 #if BOOST_COROSIO_HAS_IOCP
70 auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
71 auto& wrapper = static_cast<tcp_socket::implementation&>(*h_.get());
72 return svc.bind_socket(
73 *static_cast<detail::win_tcp_socket&>(wrapper).get_internal(), ep);
74 #else
75 14x auto& svc = static_cast<detail::tcp_service&>(h_.service());
76 28x return svc.bind_socket(
77 14x static_cast<tcp_socket::implementation&>(*h_.get()), ep);
78 #endif
79 }
80
81 void
82 33993x tcp_socket::close()
83 {
84
2/2
✓ Branch 0 taken 18209 times.
✓ Branch 1 taken 15784 times.
33993x if (!is_open())
85 18209x return;
86 15784x h_.service().close(h_);
87 33993x }
88
89 void
90 167x tcp_socket::cancel()
91 {
92
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 165 times.
167x if (!is_open())
93 2x return;
94 165x get().cancel();
95 167x }
96
97 void
98 16x tcp_socket::shutdown(shutdown_type what)
99 {
100
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10 times.
16x if (is_open())
101 {
102 // Best-effort: errors like ENOTCONN are expected and unhelpful
103 10x [[maybe_unused]] auto ec = get().shutdown(what);
104 10x }
105 16x }
106
107 native_handle_type
108 4x tcp_socket::native_handle() const noexcept
109 {
110
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4x if (!is_open())
111 {
112 #if BOOST_COROSIO_HAS_IOCP
113 return static_cast<native_handle_type>(~0ull); // INVALID_SOCKET
114 #else
115 2x return -1;
116 #endif
117 }
118 2x return get().native_handle();
119 4x }
120
121 endpoint
122 62x tcp_socket::local_endpoint() const noexcept
123 {
124
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 52 times.
62x if (!is_open())
125 10x return endpoint{};
126 52x return get().local_endpoint();
127 62x }
128
129 endpoint
130 60x tcp_socket::remote_endpoint() const noexcept
131 {
132
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 50 times.
60x if (!is_open())
133 10x return endpoint{};
134 50x return get().remote_endpoint();
135 60x }
136
137 } // namespace boost::corosio
138