TLA Line data Source code
1 : //
2 : // Copyright (c) 2026 Steve Gerbino
3 : // Copyright (c) 2026 Michael Vandeberg
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 : #ifndef BOOST_COROSIO_NATIVE_NATIVE_STREAM_FILE_HPP
12 : #define BOOST_COROSIO_NATIVE_NATIVE_STREAM_FILE_HPP
13 :
14 : #include <boost/corosio/stream_file.hpp>
15 : #include <boost/corosio/backend.hpp>
16 : #include <boost/corosio/detail/op_base.hpp>
17 :
18 : #ifndef BOOST_COROSIO_MRDOCS
19 : #if BOOST_COROSIO_HAS_EPOLL || BOOST_COROSIO_HAS_SELECT || \
20 : BOOST_COROSIO_HAS_KQUEUE
21 : #include <boost/corosio/native/detail/posix/posix_stream_file_service.hpp>
22 : #endif
23 :
24 : #if BOOST_COROSIO_HAS_URING
25 : #include <boost/corosio/native/detail/uring/uring_stream_file.hpp>
26 : #endif
27 :
28 : #if BOOST_COROSIO_HAS_IOCP
29 : #include <boost/corosio/native/detail/iocp/win_file_service.hpp>
30 : #endif
31 : #endif // !BOOST_COROSIO_MRDOCS
32 :
33 : namespace boost::corosio {
34 :
35 : /** A sequential file with devirtualized async I/O operations.
36 :
37 : This class template inherits from @ref stream_file and shadows
38 : `read_some` / `write_some` with versions that call the backend
39 : implementation directly, allowing the compiler to inline through
40 : the entire call chain.
41 :
42 : Non-async operations (`open`, `close`, `size`, `resize`, `seek`,
43 : `sync_data`, `sync_all`) remain unchanged and dispatch through
44 : the compiled library.
45 :
46 : A `native_stream_file` IS-A `stream_file` and can be passed to
47 : any function expecting `stream_file&` or `io_stream&`, in which
48 : case virtual dispatch is used transparently.
49 :
50 : @note On POSIX platforms, file I/O is dispatched to a thread
51 : pool regardless of the chosen reactor backend, so all three
52 : reactor tags (`epoll`, `select`, `kqueue`) resolve to the same
53 : underlying implementation. The `Backend` template parameter
54 : exists for API symmetry with @ref native_tcp_socket and friends.
55 : The vtable savings are smaller relative to the thread-pool /
56 : overlapped-I/O cost than they are for socket operations.
57 :
58 : @tparam Backend A backend tag value (e.g., `epoll`, `iocp`).
59 :
60 : @par Thread Safety
61 : Same as @ref stream_file.
62 :
63 : @par Example
64 : @par !example native_stream_file
65 :
66 : @see stream_file, epoll_t, iocp_t
67 : */
68 : template<auto Backend>
69 : class native_stream_file : public stream_file
70 : {
71 : using backend_type = decltype(Backend);
72 : using impl_type = typename backend_type::stream_file_type;
73 : using service_type = typename backend_type::stream_file_service_type;
74 :
75 HIT 8 : impl_type& get_impl() noexcept
76 : {
77 8 : return *static_cast<impl_type*>(h_.get());
78 : }
79 :
80 : template<class MutableBufferSequence>
81 : struct native_read_awaitable
82 : : detail::bytes_op_base<native_read_awaitable<MutableBufferSequence>>
83 : {
84 : native_stream_file& self_;
85 : MutableBufferSequence buffers_;
86 :
87 6 : native_read_awaitable(
88 : native_stream_file& self, MutableBufferSequence buffers) noexcept
89 6 : : self_(self)
90 6 : , buffers_(std::move(buffers))
91 : {
92 6 : }
93 :
94 : std::coroutine_handle<>
95 4 : dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
96 : {
97 12 : return self_.get_impl().read_some(
98 12 : 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_stream_file& self_;
107 : ConstBufferSequence buffers_;
108 :
109 6 : native_write_awaitable(
110 : native_stream_file& self, ConstBufferSequence buffers) noexcept
111 6 : : self_(self)
112 6 : , buffers_(std::move(buffers))
113 : {
114 6 : }
115 :
116 : std::coroutine_handle<>
117 4 : dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
118 : {
119 12 : return self_.get_impl().write_some(
120 12 : h, ex, buffers_, this->token_, &this->ec_, &this->bytes_);
121 : }
122 : };
123 :
124 : public:
125 : /** Construct a native stream file from an execution context.
126 :
127 : @param ctx The execution context that will own this file.
128 : */
129 16 : explicit native_stream_file(capy::execution_context& ctx)
130 16 : : io_object(create_handle<service_type>(ctx))
131 : {
132 16 : }
133 :
134 : /** Construct a native stream file from an executor.
135 :
136 : @param ex The executor whose context will own this file.
137 : */
138 : template<class Ex>
139 : requires(!std::same_as<std::remove_cvref_t<Ex>, native_stream_file>) &&
140 : capy::Executor<Ex>
141 : explicit native_stream_file(Ex const& ex) : native_stream_file(ex.context())
142 : {
143 : }
144 :
145 : /// Move construct.
146 : native_stream_file(native_stream_file&&) noexcept = default;
147 :
148 : /// Move assign.
149 : native_stream_file& operator=(native_stream_file&&) noexcept = default;
150 :
151 : native_stream_file(native_stream_file const&) = delete;
152 : native_stream_file& operator=(native_stream_file const&) = delete;
153 :
154 : /** Asynchronously read data from the file.
155 :
156 : Calls the backend implementation directly, bypassing virtual
157 : dispatch. Otherwise identical to @ref io_stream::read_some.
158 : */
159 : template<capy::MutableBufferSequence MB>
160 6 : [[nodiscard]] auto read_some(MB const& buffers)
161 : {
162 6 : return native_read_awaitable<MB>(*this, buffers);
163 : }
164 :
165 : /** Asynchronously write data to the file.
166 :
167 : Calls the backend implementation directly, bypassing virtual
168 : dispatch. Otherwise identical to @ref io_stream::write_some.
169 : */
170 : template<capy::ConstBufferSequence CB>
171 6 : [[nodiscard]] auto write_some(CB const& buffers)
172 : {
173 6 : return native_write_awaitable<CB>(*this, buffers);
174 : }
175 : };
176 :
177 : } // namespace boost::corosio
178 :
179 : #endif // BOOST_COROSIO_NATIVE_NATIVE_STREAM_FILE_HPP
|