TLA Line data 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_STREAM_SERVICE_HPP
11 : #define BOOST_COROSIO_NATIVE_DETAIL_EPOLL_EPOLL_LOCAL_STREAM_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_stream_service.hpp>
19 :
20 : #include <boost/corosio/native/detail/epoll/epoll_local_stream_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_stream_service final
36 : : public reactor_socket_service<
37 : epoll_local_stream_service,
38 : local_stream_service,
39 : epoll_scheduler,
40 : epoll_local_stream_socket>
41 : {
42 : public:
43 HIT 355 : explicit epoll_local_stream_service(capy::execution_context& ctx)
44 355 : : reactor_socket_service(ctx)
45 : {
46 355 : }
47 :
48 : std::error_code open_socket(
49 : local_stream_socket::implementation& impl,
50 : int family,
51 : int type,
52 : int protocol) override;
53 :
54 : std::error_code assign_socket(
55 : local_stream_socket::implementation& impl,
56 : int fd) override;
57 : };
58 :
59 : // Op implementations
60 :
61 : inline void
62 MIS 0 : epoll_local_connect_op::cancel() noexcept
63 : {
64 0 : if (socket_impl_)
65 0 : socket_impl_->cancel_single_op(*this);
66 : else
67 0 : request_cancel();
68 0 : }
69 :
70 : inline void
71 0 : epoll_local_read_op::cancel() noexcept
72 : {
73 0 : if (socket_impl_)
74 0 : socket_impl_->cancel_single_op(*this);
75 : else
76 0 : request_cancel();
77 0 : }
78 :
79 : inline void
80 0 : epoll_local_write_op::cancel() noexcept
81 : {
82 0 : if (socket_impl_)
83 0 : socket_impl_->cancel_single_op(*this);
84 : else
85 0 : request_cancel();
86 0 : }
87 :
88 : inline void
89 HIT 3 : epoll_local_stream_op::operator()()
90 : {
91 3 : complete_io_op(*this);
92 3 : }
93 :
94 : inline void
95 2 : epoll_local_connect_op::operator()()
96 : {
97 2 : complete_connect_op(*this);
98 2 : }
99 :
100 : // Socket implementations
101 :
102 17 : inline epoll_local_stream_socket::epoll_local_stream_socket(
103 17 : epoll_local_stream_service& svc) noexcept
104 17 : : reactor_stream_socket(svc)
105 : {
106 17 : }
107 :
108 17 : inline epoll_local_stream_socket::~epoll_local_stream_socket() = default;
109 :
110 : inline std::coroutine_handle<>
111 2 : epoll_local_stream_socket::connect(
112 : std::coroutine_handle<> h,
113 : capy::executor_ref ex,
114 : corosio::local_endpoint ep,
115 : std::stop_token token,
116 : std::error_code* ec)
117 : {
118 2 : return do_connect(h, ex, ep, token, ec);
119 : }
120 :
121 : inline std::coroutine_handle<>
122 1 : epoll_local_stream_socket::read_some(
123 : std::coroutine_handle<> h,
124 : capy::executor_ref ex,
125 : buffer_param param,
126 : std::stop_token token,
127 : std::error_code* ec,
128 : std::size_t* bytes_out)
129 : {
130 1 : return do_read_some(h, ex, param, token, ec, bytes_out);
131 : }
132 :
133 : inline std::coroutine_handle<>
134 2 : epoll_local_stream_socket::write_some(
135 : std::coroutine_handle<> h,
136 : capy::executor_ref ex,
137 : buffer_param param,
138 : std::stop_token token,
139 : std::error_code* ec,
140 : std::size_t* bytes_out)
141 : {
142 2 : return do_write_some(h, ex, param, token, ec, bytes_out);
143 : }
144 :
145 : inline void
146 MIS 0 : epoll_local_stream_socket::cancel() noexcept
147 : {
148 0 : do_cancel();
149 0 : }
150 :
151 : inline void
152 HIT 59 : epoll_local_stream_socket::close_socket() noexcept
153 : {
154 59 : do_close_socket();
155 59 : }
156 :
157 : inline native_handle_type
158 1 : epoll_local_stream_socket::release_socket() noexcept
159 : {
160 1 : return this->do_release_socket();
161 : }
162 :
163 : // Service implementations
164 :
165 : inline std::error_code
166 4 : epoll_local_stream_service::open_socket(
167 : local_stream_socket::implementation& impl,
168 : int family,
169 : int type,
170 : int protocol)
171 : {
172 4 : auto* epoll_impl = static_cast<epoll_local_stream_socket*>(&impl);
173 4 : epoll_impl->close_socket();
174 :
175 4 : int fd = ::socket(family, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol);
176 4 : if (fd < 0)
177 MIS 0 : return make_err(errno);
178 :
179 HIT 4 : epoll_impl->fd_ = fd;
180 :
181 4 : epoll_impl->desc_state_.fd = fd;
182 : {
183 4 : std::lock_guard lock(epoll_impl->desc_state_.mutex);
184 4 : epoll_impl->desc_state_.read_op = nullptr;
185 4 : epoll_impl->desc_state_.write_op = nullptr;
186 4 : epoll_impl->desc_state_.connect_op = nullptr;
187 4 : }
188 4 : scheduler().register_descriptor(fd, &epoll_impl->desc_state_);
189 :
190 4 : return {};
191 : }
192 :
193 : inline std::error_code
194 8 : epoll_local_stream_service::assign_socket(
195 : local_stream_socket::implementation& impl,
196 : int fd)
197 : {
198 8 : if (fd < 0)
199 MIS 0 : return make_err(EBADF);
200 :
201 HIT 8 : auto* epoll_impl = static_cast<epoll_local_stream_socket*>(&impl);
202 8 : epoll_impl->close_socket();
203 :
204 8 : epoll_impl->fd_ = fd;
205 :
206 8 : epoll_impl->desc_state_.fd = fd;
207 : {
208 8 : std::lock_guard lock(epoll_impl->desc_state_.mutex);
209 8 : epoll_impl->desc_state_.read_op = nullptr;
210 8 : epoll_impl->desc_state_.write_op = nullptr;
211 8 : epoll_impl->desc_state_.connect_op = nullptr;
212 8 : }
213 8 : scheduler().register_descriptor(fd, &epoll_impl->desc_state_);
214 :
215 8 : return {};
216 : }
217 :
218 : } // namespace boost::corosio::detail
219 :
220 : #endif // BOOST_COROSIO_HAS_EPOLL
221 :
222 : #endif // BOOST_COROSIO_NATIVE_DETAIL_EPOLL_EPOLL_LOCAL_STREAM_SERVICE_HPP
|