include/boost/corosio/native/detail/epoll/epoll_local_datagram_service.hpp

60.6% Lines (57/94) 60.9% List of functions (14/23)
epoll_local_datagram_service.hpp
f(x) Functions (23)
Function Calls Lines Blocks
boost::corosio::detail::epoll_local_datagram_service::epoll_local_datagram_service(boost::capy::execution_context&) :43 356x 100.0% 100.0% boost::corosio::detail::epoll_local_send_to_op::cancel() :66 0 0.0% 0.0% boost::corosio::detail::epoll_local_recv_from_op::cancel() :75 0 0.0% 0.0% boost::corosio::detail::epoll_local_dgram_connect_op::cancel() :86 0 0.0% 0.0% boost::corosio::detail::epoll_local_dgram_send_op::cancel() :95 0 0.0% 0.0% boost::corosio::detail::epoll_local_dgram_recv_op::cancel() :104 0 0.0% 0.0% boost::corosio::detail::epoll_local_datagram_op::operator()() :115 6x 100.0% 100.0% boost::corosio::detail::epoll_local_recv_from_op::operator()() :121 2x 100.0% 100.0% boost::corosio::detail::epoll_local_dgram_connect_op::operator()() :127 0 0.0% 0.0% boost::corosio::detail::epoll_local_dgram_recv_op::operator()() :133 1x 100.0% 100.0% boost::corosio::detail::epoll_local_datagram_socket::epoll_local_datagram_socket(boost::corosio::detail::epoll_local_datagram_service&) :141 17x 100.0% 100.0% boost::corosio::detail::epoll_local_datagram_socket::~epoll_local_datagram_socket() :147 17x 100.0% 100.0% boost::corosio::detail::epoll_local_datagram_socket::send_to(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref, boost::corosio::buffer_param, boost::corosio::local_endpoint, int, std::stop_token, std::error_code*, unsigned long*) :152 3x 100.0% 100.0% boost::corosio::detail::epoll_local_datagram_socket::recv_from(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref, boost::corosio::buffer_param, boost::corosio::local_endpoint*, int, std::stop_token, std::error_code*, unsigned long*) :166 4x 100.0% 100.0% boost::corosio::detail::epoll_local_datagram_socket::connect(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref, boost::corosio::local_endpoint, std::stop_token, std::error_code*) :182 0 0.0% 0.0% boost::corosio::detail::epoll_local_datagram_socket::send(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref, boost::corosio::buffer_param, int, std::stop_token, std::error_code*, unsigned long*) :193 4x 100.0% 100.0% boost::corosio::detail::epoll_local_datagram_socket::recv(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref, boost::corosio::buffer_param, int, std::stop_token, std::error_code*, unsigned long*) :206 5x 100.0% 100.0% boost::corosio::detail::epoll_local_datagram_socket::cancel() :219 0 0.0% 0.0% boost::corosio::detail::epoll_local_datagram_socket::close_socket() :225 66x 100.0% 100.0% boost::corosio::detail::epoll_local_datagram_socket::release_socket() :231 0 0.0% 0.0% boost::corosio::detail::epoll_local_datagram_service::open_socket(boost::corosio::local_datagram_socket::implementation&, int, int, int) :239 10x 93.3% 92.0% boost::corosio::detail::epoll_local_datagram_service::assign_socket(boost::corosio::local_datagram_socket::implementation&, int) :267 6x 92.9% 92.0% boost::corosio::detail::epoll_local_datagram_service::bind_socket(boost::corosio::local_datagram_socket::implementation&, boost::corosio::local_endpoint) :292 8x 100.0% 100.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_EPOLL_EPOLL_LOCAL_DATAGRAM_SERVICE_HPP
11 #define BOOST_COROSIO_NATIVE_DETAIL_EPOLL_EPOLL_LOCAL_DATAGRAM_SERVICE_HPP
12
13 #include <boost/corosio/detail/platform.hpp>
14
15 #if BOOST_COROSIO_HAS_EPOLL
16
17 #include <boost/corosio/detail/config.hpp>
18 #include <boost/corosio/detail/local_datagram_service.hpp>
19
20 #include <boost/corosio/native/detail/epoll/epoll_local_datagram_socket.hpp>
21 #include <boost/corosio/native/detail/epoll/epoll_scheduler.hpp>
22 #include <boost/corosio/native/detail/reactor/reactor_socket_service.hpp>
23
24 #include <boost/corosio/native/detail/reactor/reactor_op_complete.hpp>
25
26 #include <coroutine>
27
28 #include <errno.h>
29 #include <sys/socket.h>
30 #include <sys/un.h>
31 #include <unistd.h>
32
33 namespace boost::corosio::detail {
34
35 class BOOST_COROSIO_DECL epoll_local_datagram_service final
36 : public reactor_socket_service<
37 epoll_local_datagram_service,
38 local_datagram_service,
39 epoll_scheduler,
40 epoll_local_datagram_socket>
41 {
42 public:
43 356x explicit epoll_local_datagram_service(capy::execution_context& ctx)
44 356x : reactor_socket_service(ctx)
45 {
46 356x }
47
48 std::error_code open_socket(
49 local_datagram_socket::implementation& impl,
50 int family,
51 int type,
52 int protocol) override;
53
54 std::error_code assign_socket(
55 local_datagram_socket::implementation& impl,
56 native_handle_type fd) override;
57
58 std::error_code bind_socket(
59 local_datagram_socket::implementation& impl,
60 corosio::local_endpoint ep) override;
61 };
62
63 // Cancellation for connectionless ops
64
65 inline void
66 epoll_local_send_to_op::cancel() noexcept
67 {
68 if (socket_impl_)
69 socket_impl_->cancel_single_op(*this);
70 else
71 request_cancel();
72 }
73
74 inline void
75 epoll_local_recv_from_op::cancel() noexcept
76 {
77 if (socket_impl_)
78 socket_impl_->cancel_single_op(*this);
79 else
80 request_cancel();
81 }
82
83 // Cancellation for connected-mode ops
84
85 inline void
86 epoll_local_dgram_connect_op::cancel() noexcept
87 {
88 if (socket_impl_)
89 socket_impl_->cancel_single_op(*this);
90 else
91 request_cancel();
92 }
93
94 inline void
95 epoll_local_dgram_send_op::cancel() noexcept
96 {
97 if (socket_impl_)
98 socket_impl_->cancel_single_op(*this);
99 else
100 request_cancel();
101 }
102
103 inline void
104 epoll_local_dgram_recv_op::cancel() noexcept
105 {
106 if (socket_impl_)
107 socket_impl_->cancel_single_op(*this);
108 else
109 request_cancel();
110 }
111
112 // Completion handlers
113
114 inline void
115 6x epoll_local_datagram_op::operator()()
116 {
117 6x complete_io_op(*this);
118 6x }
119
120 inline void
121 2x epoll_local_recv_from_op::operator()()
122 {
123 2x complete_datagram_op(*this, this->source_out);
124 2x }
125
126 inline void
127 epoll_local_dgram_connect_op::operator()()
128 {
129 complete_connect_op(*this);
130 }
131
132 inline void
133 1x epoll_local_dgram_recv_op::operator()()
134 {
135 // Datagram completion: do not map 0 bytes to EOF
136 1x complete_dgram_recv_op(*this);
137 1x }
138
139 // Socket construction/destruction
140
141 17x inline epoll_local_datagram_socket::epoll_local_datagram_socket(
142 17x epoll_local_datagram_service& svc) noexcept
143 17x : reactor_datagram_socket(svc)
144 {
145 17x }
146
147 17x inline epoll_local_datagram_socket::~epoll_local_datagram_socket() = default;
148
149 // Connectionless I/O
150
151 inline std::coroutine_handle<>
152 3x epoll_local_datagram_socket::send_to(
153 std::coroutine_handle<> h,
154 capy::executor_ref ex,
155 buffer_param buf,
156 corosio::local_endpoint dest,
157 int flags,
158 std::stop_token token,
159 std::error_code* ec,
160 std::size_t* bytes_out)
161 {
162 3x return do_send_to(h, ex, buf, dest, flags, token, ec, bytes_out);
163 }
164
165 inline std::coroutine_handle<>
166 4x epoll_local_datagram_socket::recv_from(
167 std::coroutine_handle<> h,
168 capy::executor_ref ex,
169 buffer_param buf,
170 corosio::local_endpoint* source,
171 int flags,
172 std::stop_token token,
173 std::error_code* ec,
174 std::size_t* bytes_out)
175 {
176 4x return do_recv_from(h, ex, buf, source, flags, token, ec, bytes_out);
177 }
178
179 // Connected-mode I/O
180
181 inline std::coroutine_handle<>
182 epoll_local_datagram_socket::connect(
183 std::coroutine_handle<> h,
184 capy::executor_ref ex,
185 corosio::local_endpoint ep,
186 std::stop_token token,
187 std::error_code* ec)
188 {
189 return do_connect(h, ex, ep, token, ec);
190 }
191
192 inline std::coroutine_handle<>
193 4x epoll_local_datagram_socket::send(
194 std::coroutine_handle<> h,
195 capy::executor_ref ex,
196 buffer_param buf,
197 int flags,
198 std::stop_token token,
199 std::error_code* ec,
200 std::size_t* bytes_out)
201 {
202 4x return do_send(h, ex, buf, flags, token, ec, bytes_out);
203 }
204
205 inline std::coroutine_handle<>
206 5x epoll_local_datagram_socket::recv(
207 std::coroutine_handle<> h,
208 capy::executor_ref ex,
209 buffer_param buf,
210 int flags,
211 std::stop_token token,
212 std::error_code* ec,
213 std::size_t* bytes_out)
214 {
215 5x return do_recv(h, ex, buf, flags, token, ec, bytes_out);
216 }
217
218 inline void
219 epoll_local_datagram_socket::cancel() noexcept
220 {
221 do_cancel();
222 }
223
224 inline void
225 66x epoll_local_datagram_socket::close_socket() noexcept
226 {
227 66x do_close_socket();
228 66x }
229
230 inline native_handle_type
231 epoll_local_datagram_socket::release_socket() noexcept
232 {
233 return this->do_release_socket();
234 }
235
236 // Service implementations
237
238 inline std::error_code
239 10x epoll_local_datagram_service::open_socket(
240 local_datagram_socket::implementation& impl,
241 int family,
242 int type,
243 int protocol)
244 {
245 10x auto* epoll_impl = static_cast<epoll_local_datagram_socket*>(&impl);
246 10x epoll_impl->close_socket();
247
248 10x int fd = ::socket(family, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol);
249 10x if (fd < 0)
250 return make_err(errno);
251
252 10x epoll_impl->fd_ = fd;
253
254 10x epoll_impl->desc_state_.fd = fd;
255 {
256 10x std::lock_guard lock(epoll_impl->desc_state_.mutex);
257 10x epoll_impl->desc_state_.read_op = nullptr;
258 10x epoll_impl->desc_state_.write_op = nullptr;
259 10x epoll_impl->desc_state_.connect_op = nullptr;
260 10x }
261 10x scheduler().register_descriptor(fd, &epoll_impl->desc_state_);
262
263 10x return {};
264 }
265
266 inline std::error_code
267 6x epoll_local_datagram_service::assign_socket(
268 local_datagram_socket::implementation& impl,
269 native_handle_type fd)
270 {
271 6x if (fd < 0)
272 return make_err(EBADF);
273
274 6x auto* epoll_impl = static_cast<epoll_local_datagram_socket*>(&impl);
275 6x epoll_impl->close_socket();
276
277 6x epoll_impl->fd_ = fd;
278
279 6x epoll_impl->desc_state_.fd = fd;
280 {
281 6x std::lock_guard lock(epoll_impl->desc_state_.mutex);
282 6x epoll_impl->desc_state_.read_op = nullptr;
283 6x epoll_impl->desc_state_.write_op = nullptr;
284 6x epoll_impl->desc_state_.connect_op = nullptr;
285 6x }
286 6x scheduler().register_descriptor(fd, &epoll_impl->desc_state_);
287
288 6x return {};
289 }
290
291 inline std::error_code
292 8x epoll_local_datagram_service::bind_socket(
293 local_datagram_socket::implementation& impl,
294 corosio::local_endpoint ep)
295 {
296 8x return static_cast<epoll_local_datagram_socket*>(&impl)->do_bind(ep);
297 }
298
299 } // namespace boost::corosio::detail
300
301 #endif // BOOST_COROSIO_HAS_EPOLL
302
303 #endif // BOOST_COROSIO_NATIVE_DETAIL_EPOLL_EPOLL_LOCAL_DATAGRAM_SERVICE_HPP
304