src/corosio/src/tcp_socket.cpp

100.0% Lines (57 / 57) 100.0% Functions (13 / 13)
tcp_socket.cpp
f(x) Functions (13)
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
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/native/detail/endpoint_convert.hpp>
13 #include <boost/corosio/detail/except.hpp>
14 #include <boost/corosio/detail/platform.hpp>
15
16 #include "src/detail/use_backend_service.hpp"
17
18 #if BOOST_COROSIO_HAS_IOCP
19 #include <boost/corosio/native/detail/iocp/win_tcp_acceptor_service.hpp>
20 #else
21 #include <boost/corosio/detail/tcp_service.hpp>
22 #endif
23
24 namespace boost::corosio {
25
26 namespace {
27
28 #if BOOST_COROSIO_HAS_IOCP
29 using tcp_service_key = detail::win_tcp_service;
30 #else
31 using tcp_service_key = detail::tcp_service;
32 #endif
33
34 } // namespace
35
36 9985x tcp_socket::~tcp_socket()
37 {
38 9969x close();
39 9985x }
40
41 9226x tcp_socket::tcp_socket(capy::execution_context& ctx)
42 9226x : io_object(handle(
43 ctx,
44 9226x detail::use_backend_service<detail::tcp_service_of, tcp_service_key>(
45 27678x ctx)))
46 {
47 9226x }
48
49 std::error_code
50 4602x tcp_socket::open(family f) noexcept
51 {
52 4602x if (is_open())
53 4x return {};
54 4598x return open_for_family(detail::native_family(f), SOCK_STREAM, IPPROTO_TCP);
55 }
56
57 std::error_code
58 4598x tcp_socket::open_for_family(int family, int type, int protocol) noexcept
59 {
60 #if BOOST_COROSIO_HAS_IOCP
61 auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
62 auto& wrapper = static_cast<tcp_socket::implementation&>(*h_.get());
63 std::error_code ec = svc.open_socket(
64 *static_cast<detail::win_tcp_socket&>(wrapper).get_internal(), family,
65 type, protocol);
66 #else
67 4598x auto& svc = static_cast<detail::tcp_service&>(h_.service());
68 4598x std::error_code ec = svc.open_socket(
69 4598x static_cast<tcp_socket::implementation&>(*h_.get()), family, type,
70 protocol);
71 #endif
72 4598x return ec;
73 }
74
75 std::error_code
76 29x tcp_socket::assign(native_handle_type fd) noexcept
77 {
78 #if BOOST_COROSIO_HAS_IOCP
79 auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
80 auto& wrapper = static_cast<tcp_socket::implementation&>(*h_.get());
81 std::error_code ec = svc.assign_socket(
82 *static_cast<detail::win_tcp_socket&>(wrapper).get_internal(), fd);
83 #else
84 29x auto& svc = static_cast<detail::tcp_service&>(h_.service());
85 29x std::error_code ec = svc.assign_socket(
86 29x static_cast<tcp_socket::implementation&>(*h_.get()), fd);
87 #endif
88 29x return ec;
89 }
90
91 native_handle_type
92 6x tcp_socket::release()
93 {
94 6x if (!is_open())
95 2x detail::throw_system_error(
96 2x make_error_code(std::errc::bad_file_descriptor),
97 "tcp_socket::release");
98 4x return get().release_socket();
99 }
100
101 std::error_code
102 21x tcp_socket::bind(endpoint ep) noexcept
103 {
104 21x if (!is_open())
105 2x return make_error_code(std::errc::bad_file_descriptor);
106 #if BOOST_COROSIO_HAS_IOCP
107 auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
108 auto& wrapper = static_cast<tcp_socket::implementation&>(*h_.get());
109 return svc.bind_socket(
110 *static_cast<detail::win_tcp_socket&>(wrapper).get_internal(), ep);
111 #else
112 19x auto& svc = static_cast<detail::tcp_service&>(h_.service());
113 19x return svc.bind_socket(
114 38x static_cast<tcp_socket::implementation&>(*h_.get()), ep);
115 #endif
116 }
117
118 void
119 18546x tcp_socket::close() noexcept
120 {
121 18546x if (!is_open())
122 9488x return;
123 9058x h_.service().close(h_);
124 }
125
126 void
127 216x tcp_socket::cancel() noexcept
128 {
129 216x if (!is_open())
130 2x return;
131 214x get().cancel();
132 }
133
134 std::error_code
135 27x tcp_socket::shutdown(shutdown_type what) noexcept
136 {
137 27x if (!is_open())
138 6x return make_error_code(std::errc::bad_file_descriptor);
139 21x return get().shutdown(what);
140 }
141
142 native_handle_type
143 63x tcp_socket::native_handle() const noexcept
144 {
145 63x if (!is_open())
146 {
147 #if BOOST_COROSIO_HAS_IOCP
148 return static_cast<native_handle_type>(~0ull); // INVALID_SOCKET
149 #else
150 2x return -1;
151 #endif
152 }
153 61x return get().native_handle();
154 }
155
156 endpoint
157 68x tcp_socket::local_endpoint() const noexcept
158 {
159 68x if (!is_open())
160 10x return endpoint{};
161 58x return get().local_endpoint();
162 }
163
164 endpoint
165 68x tcp_socket::remote_endpoint() const noexcept
166 {
167 68x if (!is_open())
168 10x return endpoint{};
169 58x return get().remote_endpoint();
170 }
171
172 } // namespace boost::corosio
173