src/corosio/src/tcp_socket.cpp

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