src/corosio/src/tcp_socket.cpp

82.9% Lines (34/41) 90.0% Functions (9/10)
src/corosio/src/tcp_socket.cpp
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/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_acceptor_service.hpp>
17 #else
18 #include <boost/corosio/detail/socket_service.hpp>
19 #endif
20
21 namespace boost::corosio {
22
23 15652 tcp_socket::~tcp_socket()
24 {
25 15652 close();
26 15652 }
27
28 15454 tcp_socket::tcp_socket(capy::execution_context& ctx)
29 #if BOOST_COROSIO_HAS_IOCP
30 : io_object(create_handle<detail::win_sockets>(ctx))
31 #else
32 15454 : io_object(create_handle<detail::socket_service>(ctx))
33 #endif
34 {
35 15454 }
36
37 void
38 7722 tcp_socket::open(tcp proto)
39 {
40 7722 if (is_open())
41 return;
42 7722 open_for_family(proto.family(), proto.type(), proto.protocol());
43 }
44
45 void
46 7722 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_sockets&>(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_socket&>(wrapper).get_internal(),
53 family, type, protocol);
54 #else
55 7722 auto& svc = static_cast<detail::socket_service&>(h_.service());
56 7722 std::error_code ec = svc.open_socket(
57 7722 static_cast<tcp_socket::implementation&>(*h_.get()),
58 family, type, protocol);
59 #endif
60 7722 if (ec)
61 detail::throw_system_error(ec, "tcp_socket::open");
62 7722 }
63
64 void
65 31085 tcp_socket::close()
66 {
67 31085 if (!is_open())
68 15676 return;
69 15409 h_.service().close(h_);
70 }
71
72 void
73 364 tcp_socket::cancel()
74 {
75 364 if (!is_open())
76 return;
77 364 get().cancel();
78 }
79
80 void
81 12 tcp_socket::shutdown(shutdown_type what)
82 {
83 12 if (is_open())
84 {
85 // Best-effort: errors like ENOTCONN are expected and unhelpful
86 6 [[maybe_unused]] auto ec = get().shutdown(what);
87 }
88 12 }
89
90 native_handle_type
91 tcp_socket::native_handle() const noexcept
92 {
93 if (!is_open())
94 {
95 #if BOOST_COROSIO_HAS_IOCP
96 return static_cast<native_handle_type>(~0ull); // INVALID_SOCKET
97 #else
98 return -1;
99 #endif
100 }
101 return get().native_handle();
102 }
103
104 endpoint
105 48 tcp_socket::local_endpoint() const noexcept
106 {
107 48 if (!is_open())
108 10 return endpoint{};
109 38 return get().local_endpoint();
110 }
111
112 endpoint
113 52 tcp_socket::remote_endpoint() const noexcept
114 {
115 52 if (!is_open())
116 10 return endpoint{};
117 42 return get().remote_endpoint();
118 }
119
120 } // namespace boost::corosio
121