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 10755x tcp_socket::~tcp_socket()
37 {
38 10739x close();
39 10755x }
40
41 9966x tcp_socket::tcp_socket(capy::execution_context& ctx)
42 9966x : io_object(handle(
43 ctx,
44 9966x detail::use_backend_service<detail::tcp_service_of, tcp_service_key>(
45 29898x ctx)))
46 {
47 9966x }
48
49 std::error_code
50 4976x tcp_socket::open(family f) noexcept
51 {
52 4976x if (is_open())
53 4x return {};
54 4972x return open_for_family(detail::native_family(f), SOCK_STREAM, IPPROTO_TCP);
55 }
56
57 std::error_code
58 4972x 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& sock = static_cast<detail::win_tcp_socket&>(*h_.get());
63 std::error_code ec = svc.open_socket(sock, family, type, protocol);
64 #else
65 4972x auto& svc = static_cast<detail::tcp_service&>(h_.service());
66 4972x std::error_code ec = svc.open_socket(
67 4972x static_cast<tcp_socket::implementation&>(*h_.get()), family, type,
68 protocol);
69 #endif
70 4972x return ec;
71 }
72
73 std::error_code
74 29x tcp_socket::assign(native_handle_type fd) noexcept
75 {
76 #if BOOST_COROSIO_HAS_IOCP
77 auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
78 auto& sock = static_cast<detail::win_tcp_socket&>(*h_.get());
79 std::error_code ec = svc.assign_socket(sock, fd);
80 #else
81 29x auto& svc = static_cast<detail::tcp_service&>(h_.service());
82 29x std::error_code ec = svc.assign_socket(
83 29x static_cast<tcp_socket::implementation&>(*h_.get()), fd);
84 #endif
85 29x return ec;
86 }
87
88 native_handle_type
89 6x tcp_socket::release()
90 {
91 6x if (!is_open())
92 2x detail::throw_system_error(
93 2x make_error_code(std::errc::bad_file_descriptor),
94 "tcp_socket::release");
95 4x return get().release_socket();
96 }
97
98 std::error_code
99 21x tcp_socket::bind(endpoint ep) noexcept
100 {
101 21x if (!is_open())
102 2x return make_error_code(std::errc::bad_file_descriptor);
103 #if BOOST_COROSIO_HAS_IOCP
104 auto& svc = static_cast<detail::win_tcp_service&>(h_.service());
105 auto& sock = static_cast<detail::win_tcp_socket&>(*h_.get());
106 return svc.bind_socket(sock, ep);
107 #else
108 19x auto& svc = static_cast<detail::tcp_service&>(h_.service());
109 19x return svc.bind_socket(
110 38x static_cast<tcp_socket::implementation&>(*h_.get()), ep);
111 #endif
112 }
113
114 void
115 19950x tcp_socket::close() noexcept
116 {
117 19950x if (!is_open())
118 10150x return;
119 9800x h_.service().close(h_);
120 }
121
122 void
123 216x tcp_socket::cancel() noexcept
124 {
125 216x if (!is_open())
126 2x return;
127 214x get().cancel();
128 }
129
130 std::error_code
131 27x tcp_socket::shutdown(shutdown_type what) noexcept
132 {
133 27x if (!is_open())
134 6x return make_error_code(std::errc::bad_file_descriptor);
135 21x return get().shutdown(what);
136 }
137
138 native_handle_type
139 63x tcp_socket::native_handle() const noexcept
140 {
141 63x if (!is_open())
142 {
143 #if BOOST_COROSIO_HAS_IOCP
144 return static_cast<native_handle_type>(~0ull); // INVALID_SOCKET
145 #else
146 2x return -1;
147 #endif
148 }
149 61x return get().native_handle();
150 }
151
152 endpoint
153 68x tcp_socket::local_endpoint() const noexcept
154 {
155 68x if (!is_open())
156 10x return endpoint{};
157 58x return get().local_endpoint();
158 }
159
160 endpoint
161 68x tcp_socket::remote_endpoint() const noexcept
162 {
163 68x if (!is_open())
164 10x return endpoint{};
165 58x return get().remote_endpoint();
166 }
167
168 } // namespace boost::corosio
169