src/corosio/src/tcp_socket.cpp

100.0% Lines (59 / 59) 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 // 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 25208x tcp_socket::~tcp_socket()
39 {
40 25190x close();
41 25208x }
42
43 19092x tcp_socket::tcp_socket(capy::execution_context& ctx)
44 19092x : io_object(handle(
45 ctx,
46 19092x detail::use_backend_service<detail::tcp_service_of, tcp_service_key>(
47 57276x ctx)))
48 {
49 19092x }
50
51 std::error_code
52 8258x tcp_socket::open(family f) noexcept
53 {
54 8258x if (is_open())
55 4x return {};
56 8254x return open_for_family(detail::native_family(f), SOCK_STREAM, IPPROTO_TCP);
57 }
58
59 std::error_code
60 8254x tcp_socket::open_for_family(int family, int type, int protocol) noexcept
61 {
62 #if BOOST_COROSIO_HAS_IOCP
63 auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
64 auto& sock = static_cast<detail::win_tcp_socket&>(*h_.get());
65 std::error_code ec = svc.open_socket(sock, family, type, protocol);
66 #else
67 8254x auto& svc = static_cast<detail::tcp_service&>(h_.service());
68 8254x std::error_code ec = svc.open_socket(
69 8254x static_cast<tcp_socket::implementation&>(*h_.get()), family, type,
70 protocol);
71 #endif
72 8254x return ec;
73 }
74
75 std::error_code
76 5035x tcp_socket::assign(native_handle_type fd) noexcept
77 {
78 5035x if (is_open())
79 8x return make_error_code(error::already_open);
80 #if BOOST_COROSIO_HAS_IOCP
81 auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
82 auto& sock = static_cast<detail::win_tcp_socket&>(*h_.get());
83 std::error_code ec = svc.assign_socket(sock, fd);
84 #else
85 5027x auto& svc = static_cast<detail::tcp_service&>(h_.service());
86 5027x std::error_code ec = svc.assign_socket(
87 5027x static_cast<tcp_socket::implementation&>(*h_.get()), fd);
88 #endif
89 5027x return ec;
90 }
91
92 native_handle_type
93 8x tcp_socket::release()
94 {
95 8x if (!is_open())
96 2x detail::throw_system_error(
97 2x make_error_code(std::errc::bad_file_descriptor),
98 "tcp_socket::release");
99 6x return get().release_socket();
100 }
101
102 std::error_code
103 21x tcp_socket::bind(endpoint ep) noexcept
104 {
105 21x if (!is_open())
106 2x return make_error_code(std::errc::bad_file_descriptor);
107 #if BOOST_COROSIO_HAS_IOCP
108 auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
109 auto& sock = static_cast<detail::win_tcp_socket&>(*h_.get());
110 return svc.bind_socket(sock, 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 36538x tcp_socket::close() noexcept
120 {
121 36538x if (!is_open())
122 17643x return;
123 18895x h_.service().close(h_);
124 }
125
126 void
127 224x tcp_socket::cancel() noexcept
128 {
129 224x if (!is_open())
130 2x return;
131 222x 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 73x tcp_socket::native_handle() const noexcept
144 {
145 73x 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 71x 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 84x tcp_socket::remote_endpoint() const noexcept
166 {
167 84x if (!is_open())
168 10x return endpoint{};
169 74x return get().remote_endpoint();
170 }
171
172 } // namespace boost::corosio
173