include/boost/corosio/native/native_posix_stream_descriptor.hpp

100.0% Lines (31 / 31) 100.0% Functions (30 / 30)
native_posix_stream_descriptor.hpp
f(x) Functions (30)
Function Calls Lines Blocks
boost::corosio::native_posix_stream_descriptor<boost::corosio::epoll_t{}>::get_impl() :74 4x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::select_t{}>::get_impl() :74 4x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::uring_t{}>::get_impl() :74 4x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::epoll_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::native_read_awaitable(boost::corosio::native_posix_stream_descriptor<boost::corosio::epoll_t{}>&, boost::capy::mutable_buffer) :86 3x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::select_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::native_read_awaitable(boost::corosio::native_posix_stream_descriptor<boost::corosio::select_t{}>&, boost::capy::mutable_buffer) :86 3x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::uring_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::native_read_awaitable(boost::corosio::native_posix_stream_descriptor<boost::corosio::uring_t{}>&, boost::capy::mutable_buffer) :86 3x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::epoll_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :95 2x 100.0% 75.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::select_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :95 2x 100.0% 75.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::uring_t{}>::native_read_awaitable<boost::capy::mutable_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :95 2x 100.0% 75.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::epoll_t{}>::native_write_awaitable<boost::capy::const_buffer>::native_write_awaitable(boost::corosio::native_posix_stream_descriptor<boost::corosio::epoll_t{}>&, boost::capy::const_buffer) :109 1x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::select_t{}>::native_write_awaitable<boost::capy::const_buffer>::native_write_awaitable(boost::corosio::native_posix_stream_descriptor<boost::corosio::select_t{}>&, boost::capy::const_buffer) :109 1x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::uring_t{}>::native_write_awaitable<boost::capy::const_buffer>::native_write_awaitable(boost::corosio::native_posix_stream_descriptor<boost::corosio::uring_t{}>&, boost::capy::const_buffer) :109 1x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::epoll_t{}>::native_write_awaitable<boost::capy::const_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :118 1x 100.0% 75.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::select_t{}>::native_write_awaitable<boost::capy::const_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :118 1x 100.0% 75.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::uring_t{}>::native_write_awaitable<boost::capy::const_buffer>::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :118 1x 100.0% 75.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::epoll_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_posix_stream_descriptor<boost::corosio::epoll_t{}>&, boost::corosio::wait_type) :130 2x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::select_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_posix_stream_descriptor<boost::corosio::select_t{}>&, boost::corosio::wait_type) :130 2x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::uring_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_posix_stream_descriptor<boost::corosio::uring_t{}>&, boost::corosio::wait_type) :130 2x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::epoll_t{}>::native_wait_awaitable::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :138 1x 100.0% 80.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::select_t{}>::native_wait_awaitable::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :138 1x 100.0% 80.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::uring_t{}>::native_wait_awaitable::dispatch(std::__n4861::coroutine_handle<void>, boost::capy::executor_ref) const :138 1x 100.0% 80.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::epoll_t{}>::native_posix_stream_descriptor(boost::capy::execution_context&) :150 7x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::select_t{}>::native_posix_stream_descriptor(boost::capy::execution_context&) :150 7x 100.0% 100.0% boost::corosio::native_posix_stream_descriptor<boost::corosio::uring_t{}>::native_posix_stream_descriptor(boost::capy::execution_context&) :150 7x 100.0% 100.0% auto boost::corosio::native_posix_stream_descriptor<boost::corosio::epoll_t{}>::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&) :211 3x 100.0% 100.0% auto boost::corosio::native_posix_stream_descriptor<boost::corosio::select_t{}>::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&) :211 3x 100.0% 100.0% auto boost::corosio::native_posix_stream_descriptor<boost::corosio::uring_t{}>::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer const&) :211 3x 100.0% 100.0% auto boost::corosio::native_posix_stream_descriptor<boost::corosio::epoll_t{}>::write_some<boost::capy::const_buffer>(boost::capy::const_buffer const&) :226 1x 100.0% 100.0% auto boost::corosio::native_posix_stream_descriptor<boost::corosio::select_t{}>::write_some<boost::capy::const_buffer>(boost::capy::const_buffer const&) :226 1x 100.0% 100.0% auto boost::corosio::native_posix_stream_descriptor<boost::corosio::uring_t{}>::write_some<boost::capy::const_buffer>(boost::capy::const_buffer const&) :226 1x 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_NATIVE_POSIX_STREAM_DESCRIPTOR_HPP
11 #define BOOST_COROSIO_NATIVE_NATIVE_POSIX_STREAM_DESCRIPTOR_HPP
12
13 #include <boost/corosio/detail/op_base.hpp>
14 #include <boost/corosio/posix_stream_descriptor.hpp>
15 #include <boost/corosio/backend.hpp>
16
17 #if BOOST_COROSIO_POSIX || defined(BOOST_COROSIO_MRDOCS)
18
19 #ifndef BOOST_COROSIO_MRDOCS
20 #if BOOST_COROSIO_HAS_EPOLL
21 #include <boost/corosio/native/detail/epoll/epoll_types.hpp>
22 #endif
23
24 #if BOOST_COROSIO_HAS_SELECT
25 #include <boost/corosio/native/detail/select/select_types.hpp>
26 #endif
27
28 #if BOOST_COROSIO_HAS_KQUEUE
29 #include <boost/corosio/native/detail/kqueue/kqueue_types.hpp>
30 #endif
31
32 #if BOOST_COROSIO_HAS_URING
33 // uring_types.hpp does not declare the descriptor: it was added
34 // after that header, in its own pair of files.
35 #include <boost/corosio/native/detail/uring/uring_descriptor_service.hpp>
36 #endif
37 #endif // !BOOST_COROSIO_MRDOCS
38
39 namespace boost::corosio {
40
41 /** Drives an already-open POSIX descriptor, calling the backend directly.
42
43 This class template inherits from @ref posix_stream_descriptor and
44 shadows the async operations (`read_some`, `write_some`, `wait`)
45 with versions that call the backend implementation directly.
46 This lets the compiler inline through the entire call chain.
47
48 Non-async operations (`assign`, `release`, `close`, `cancel`)
49 remain unchanged and dispatch through the compiled library.
50
51 A `native_posix_stream_descriptor` IS-A `posix_stream_descriptor` and can be
52 passed to any function expecting `posix_stream_descriptor&` or
53 `io_stream&`, in which case virtual dispatch is used
54 transparently.
55
56 @tparam Backend A backend tag value (e.g., `epoll`) whose type
57 provides the concrete implementation types.
58
59 @par Thread Safety
60 Same as @ref posix_stream_descriptor.
61
62 @par Example
63 @par !example assign_and_wait
64
65 @see posix_stream_descriptor, epoll_t, kqueue_t
66 */
67 template<auto Backend>
68 class native_posix_stream_descriptor : public posix_stream_descriptor
69 {
70 using backend_type = decltype(Backend);
71 using impl_type = typename backend_type::stream_descriptor_type;
72 using service_type = typename backend_type::stream_descriptor_service_type;
73
74 12x impl_type& get_impl() noexcept
75 {
76 12x return *static_cast<impl_type*>(h_.get());
77 }
78
79 template<class MutableBufferSequence>
80 struct native_read_awaitable
81 : detail::bytes_op_base<native_read_awaitable<MutableBufferSequence>>
82 {
83 native_posix_stream_descriptor& self_;
84 MutableBufferSequence buffers_;
85
86 9x native_read_awaitable(
87 native_posix_stream_descriptor& self,
88 MutableBufferSequence buffers) noexcept
89 9x : self_(self)
90 9x , buffers_(std::move(buffers))
91 {
92 9x }
93
94 std::coroutine_handle<>
95 6x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
96 {
97 18x return self_.get_impl().read_some(
98 18x h, ex, buffers_, this->token_, &this->ec_, &this->bytes_);
99 }
100 };
101
102 template<class ConstBufferSequence>
103 struct native_write_awaitable
104 : detail::bytes_op_base<native_write_awaitable<ConstBufferSequence>>
105 {
106 native_posix_stream_descriptor& self_;
107 ConstBufferSequence buffers_;
108
109 3x native_write_awaitable(
110 native_posix_stream_descriptor& self,
111 ConstBufferSequence buffers) noexcept
112 3x : self_(self)
113 3x , buffers_(std::move(buffers))
114 {
115 3x }
116
117 std::coroutine_handle<>
118 3x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
119 {
120 9x return self_.get_impl().write_some(
121 9x h, ex, buffers_, this->token_, &this->ec_, &this->bytes_);
122 }
123 };
124
125 struct native_wait_awaitable : detail::void_op_base<native_wait_awaitable>
126 {
127 native_posix_stream_descriptor& self_;
128 wait_type w_;
129
130 6x native_wait_awaitable(
131 native_posix_stream_descriptor& self, wait_type w) noexcept
132 6x : self_(self)
133 6x , w_(w)
134 {
135 6x }
136
137 std::coroutine_handle<>
138 3x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
139 {
140 3x return self_.get_impl().wait(h, ex, w_, this->token_, &this->ec_);
141 }
142 };
143
144 public:
145 /** Construct a `native_posix_stream_descriptor` from an execution
146 context.
147
148 @param ctx The execution context that owns this object.
149 */
150 21x explicit native_posix_stream_descriptor(capy::execution_context& ctx)
151 21x : io_object(handle(ctx, ctx.use_service<service_type>()))
152 {
153 21x }
154
155 /** Construct a `native_posix_stream_descriptor` from an executor.
156
157 The overload excludes `native_posix_stream_descriptor` itself so
158 that it cannot displace the move constructor.
159
160 @tparam Ex A type satisfying `capy::Executor`.
161 @param ex The executor whose context owns this object.
162 */
163 template<class Ex>
164 requires(!std::same_as<
165 std::remove_cvref_t<Ex>,
166 native_posix_stream_descriptor>) &&
167 capy::Executor<Ex>
168 explicit native_posix_stream_descriptor(Ex const& ex)
169 : native_posix_stream_descriptor(ex.context())
170 {
171 }
172
173 /** Transfer ownership of the descriptor from the source.
174
175 After the move, the source is in a moved-from state and may
176 only be destroyed or assigned to.
177
178 @pre No awaitables returned by the source's methods exist.
179 */
180 native_posix_stream_descriptor(native_posix_stream_descriptor&&) noexcept =
181 default;
182
183 /** Close any held descriptor and transfer ownership from the source.
184
185 After the move, the source is in a moved-from state and may
186 only be destroyed or assigned to.
187
188 @return `*this`.
189 @pre No awaitables returned by either object's methods exist.
190 */
191 native_posix_stream_descriptor&
192 operator=(native_posix_stream_descriptor&&) noexcept = default;
193
194 /// Copy construction is disabled; the handle is uniquely owned.
195 native_posix_stream_descriptor(native_posix_stream_descriptor const&) =
196 delete;
197 /// Copy assignment is disabled; the handle is uniquely owned.
198 native_posix_stream_descriptor&
199 operator=(native_posix_stream_descriptor const&) = delete;
200
201 /** Asynchronously read data from the descriptor.
202
203 Calls the backend implementation directly, bypassing virtual
204 dispatch. Otherwise identical to @ref io_stream::read_some.
205
206 @param buffers The buffer sequence to read into.
207
208 @return An awaitable yielding `(error_code, std::size_t)`.
209 */
210 template<capy::MutableBufferSequence MB>
211 9x [[nodiscard]] auto read_some(MB const& buffers)
212 {
213 9x return native_read_awaitable<MB>(*this, buffers);
214 }
215
216 /** Asynchronously write data to the descriptor.
217
218 Calls the backend implementation directly, bypassing virtual
219 dispatch. Otherwise identical to @ref io_stream::write_some.
220
221 @param buffers The buffer sequence to write from.
222
223 @return An awaitable yielding `(error_code, std::size_t)`.
224 */
225 template<capy::ConstBufferSequence CB>
226 3x [[nodiscard]] auto write_some(CB const& buffers)
227 {
228 3x return native_write_awaitable<CB>(*this, buffers);
229 }
230
231 /** Wait for readiness without transferring bytes.
232
233 Calls the backend implementation directly, bypassing virtual
234 dispatch. Otherwise identical to @ref posix_stream_descriptor::wait.
235
236 @param w The direction to wait on.
237
238 @return An awaitable yielding `io_result<>`.
239 */
240 6x [[nodiscard]] auto wait(wait_type w)
241 {
242 6x return native_wait_awaitable(*this, w);
243 }
244 };
245
246 } // namespace boost::corosio
247
248 #endif // BOOST_COROSIO_POSIX || BOOST_COROSIO_MRDOCS
249
250 #endif // BOOST_COROSIO_NATIVE_NATIVE_POSIX_STREAM_DESCRIPTOR_HPP
251