include/boost/corosio/native/detail/native_socket_base.hpp

100.0% Lines (34 / 34) 88.5% Functions (54 / 61)
native_socket_base.hpp
f(x) Functions (61)
Function Calls Lines Blocks
boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::native_socket_base() :63 137x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::native_socket_base() :63 163x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::native_socket_base() :63 1037x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::native_socket_base() :63 165x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::native_socket_base() :63 128x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::native_socket_base() :63 153x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::native_socket_base() :63 780x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::native_socket_base() :63 202x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::~native_socket_base() :71 137x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::~native_socket_base() :71 163x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::~native_socket_base() :71 1037x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::~native_socket_base() :71 165x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::~native_socket_base() :71 128x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::~native_socket_base() :71 153x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::~native_socket_base() :71 780x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::~native_socket_base() :71 202x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::native_handle() const :74 727x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::native_handle() const :74 588x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::native_handle() const :74 25098x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::native_handle() const :74 883x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::native_handle() const :74 679x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::native_handle() const :74 529x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::native_handle() const :74 20122x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::native_handle() const :74 1027x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::family() const :79 14x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::family() const :79 10x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::family() const :79 237x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::family() const :79 80x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::family() const :79 14x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::family() const :79 10x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::family() const :79 152x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::family() const :79 76x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::local_endpoint() const :85 1x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::local_endpoint() const :85 2x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::local_endpoint() const :85 29x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::local_endpoint() const :85 67x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::local_endpoint() const :85 1x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::local_endpoint() const :85 2x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::local_endpoint() const :85 29x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::local_endpoint() const :85 65x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::set_option(int, int, void const*, unsigned long) :97 11x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::set_option(int, int, void const*, unsigned long) :97 0 0.0% 0.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::set_option(int, int, void const*, unsigned long) :97 0 0.0% 0.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::set_option(int, int, void const*, unsigned long) :97 49x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::set_option(int, int, void const*, unsigned long) :97 11x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::set_option(int, int, void const*, unsigned long) :97 0 0.0% 0.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::set_option(int, int, void const*, unsigned long) :97 0 0.0% 0.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::set_option(int, int, void const*, unsigned long) :97 46x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::get_option(int, int, void*, unsigned long*) const :111 3x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::get_option(int, int, void*, unsigned long*) const :111 0 0.0% 0.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::get_option(int, int, void*, unsigned long*) const :111 48x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::get_option(int, int, void*, unsigned long*) const :111 31x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_datagram_socket, boost::corosio::local_datagram_socket::implementation, boost::corosio::local_endpoint>::get_option(int, int, void*, unsigned long*) const :111 3x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::get_option(int, int, void*, unsigned long*) const :111 0 0.0% 0.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::get_option(int, int, void*, unsigned long*) const :111 47x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_udp_socket, boost::corosio::udp_socket::implementation, boost::corosio::endpoint>::get_option(int, int, void*, unsigned long*) const :111 30x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::set_socket(int) :122 14x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::set_socket(int) :122 2687x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_local_stream_socket, boost::corosio::local_stream_socket::implementation, boost::corosio::local_endpoint>::set_socket(int) :122 13x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::select_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::set_socket(int) :122 2154x 100.0% 100.0% boost::corosio::detail::native_socket_base<boost::corosio::detail::epoll_tcp_socket, boost::corosio::tcp_socket::implementation, boost::corosio::endpoint>::do_bind(boost::corosio::endpoint const&) :141 0 0.0% 0.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Michael Vandeberg
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #ifndef BOOST_COROSIO_NATIVE_DETAIL_NATIVE_SOCKET_BASE_HPP
11 #define BOOST_COROSIO_NATIVE_DETAIL_NATIVE_SOCKET_BASE_HPP
12
13 #include <boost/corosio/detail/native_handle.hpp>
14 #include <boost/corosio/endpoint.hpp>
15 #include <boost/corosio/native/detail/endpoint_convert.hpp>
16 #include <boost/corosio/native/detail/make_err.hpp>
17
18 #include <memory>
19 #include <system_error>
20
21 #include <errno.h>
22 #include <sys/socket.h>
23
24 /*
25 Readiness/completion-agnostic socket base for the POSIX-fd backends.
26
27 Holds the part of a socket impl that does not care whether the backend
28 is readiness-based (epoll/kqueue/select, which park ops on a
29 descriptor_state) or completion-based (io_uring, which submits SQEs):
30 the file descriptor, the cached local endpoint, and the synchronous
31 accessors (native_handle / options / bind). The impl lifecycle (the
32 intrusive refcount + the owning service's recycling pool) is carried
33 by `io_object::implementation`, not by this base.
34
35 reactor_basic_socket derives from this and adds the readiness machinery
36 (descriptor_state, register_op, the cancel/close that deregister from
37 the reactor). io_uring's socket impls derive from it and add their op
38 slots + SQE submission. This is the socket-layer analogue of io_uring
39 deriving from reactor_scheduler: io_uring sockets share the reactor's
40 readiness-agnostic socket surface, while the on-EAGAIN action (park vs
41 submit-SQE) and the op model stay backend-specific.
42
43 @tparam Derived The concrete socket type (CRTP).
44 @tparam ImplBase The public vtable base (tcp_socket::implementation,
45 udp_socket::implementation, ...).
46 @tparam Endpoint The endpoint type (endpoint or local_endpoint).
47 */
48
49 namespace boost::corosio::detail {
50
51 template<class Derived, class ImplBase, class Endpoint = endpoint>
52 class native_socket_base
53 : public ImplBase
54 {
55 protected:
56 // CRTP base: not publicly constructible. The check's preferred fix
57 // (private ctor + `friend Derived`) is infeasible here — the reactor
58 // sockets reach this base through intermediate templates
59 // (reactor_stream_socket -> reactor_basic_socket) that are not `Derived`,
60 // so a private ctor would stop those intermediates from constructing it.
61 // Protected is the correct access; suppress the private-only suggestion.
62 // NOLINTNEXTLINE(bugprone-crtp-constructor-accessibility)
63 2765x native_socket_base() = default;
64
65 int fd_ = -1;
66 // mutable so a derived const local_endpoint() override can lazily fill
67 // it via getsockname() on first read (io_uring's lazy_pending state).
68 mutable Endpoint local_endpoint_;
69
70 public:
71 2765x ~native_socket_base() override = default;
72
73 /// Return the underlying file descriptor.
74 49653x native_handle_type native_handle() const noexcept override
75 {
76 49653x return fd_;
77 }
78
79 593x corosio::family family() const noexcept override
80 {
81 593x return to_family(socket_family(fd_));
82 }
83
84 /// Return the cached local endpoint.
85 196x Endpoint local_endpoint() const noexcept override
86 {
87 196x return local_endpoint_;
88 }
89
90 /// Return true if the socket has an open file descriptor.
91 bool is_open() const noexcept
92 {
93 return fd_ >= 0;
94 }
95
96 /// Set a socket option.
97 117x std::error_code set_option(
98 int level,
99 int optname,
100 void const* data,
101 std::size_t size) noexcept override
102 {
103 117x if (::setsockopt(
104 117x fd_, level, optname, data, static_cast<socklen_t>(size)) != 0)
105 8x return make_err(errno);
106 109x return {};
107 }
108
109 /// Get a socket option.
110 std::error_code
111 170x get_option(int level, int optname, void* data, std::size_t* size)
112 const noexcept override
113 {
114 170x socklen_t len = static_cast<socklen_t>(*size);
115 170x if (::getsockopt(fd_, level, optname, data, &len) != 0)
116 13x return make_err(errno);
117 157x *size = static_cast<std::size_t>(len);
118 157x return {};
119 }
120
121 /// Assign the file descriptor.
122 4868x void set_socket(int fd) noexcept
123 {
124 4868x fd_ = fd;
125 4868x }
126
127 /// Cache the local endpoint.
128 void set_local_endpoint(Endpoint ep) noexcept
129 {
130 local_endpoint_ = ep;
131 }
132
133 /** Bind the socket to a local endpoint.
134
135 Calls ::bind() and caches the resulting local endpoint via
136 getsockname(). Readiness-agnostic; usable by any fd backend.
137
138 @param ep The endpoint to bind to.
139 @return Error code on failure, empty on success.
140 */
141 274x std::error_code do_bind(Endpoint const& ep) noexcept
142 {
143 274x sockaddr_storage storage{};
144 274x socklen_t addrlen = to_sockaddr(ep, socket_family(fd_), storage);
145 274x if (::bind(fd_, reinterpret_cast<sockaddr*>(&storage), addrlen) != 0)
146 20x return make_err(errno);
147
148 254x sockaddr_storage local_storage{};
149 254x socklen_t local_len = sizeof(local_storage);
150 254x if (::getsockname(
151 254x fd_, reinterpret_cast<sockaddr*>(&local_storage), &local_len) ==
152 0)
153 193x local_endpoint_ =
154 254x from_sockaddr_as(local_storage, local_len, Endpoint{});
155
156 254x return {};
157 }
158 };
159
160 } // namespace boost::corosio::detail
161
162 #endif // BOOST_COROSIO_NATIVE_DETAIL_NATIVE_SOCKET_BASE_HPP
163