TLA Line data Source code
1 : //
2 : // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2026 Steve Gerbino
4 : // Copyright (c) 2026 Michael Vandeberg
5 : //
6 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
7 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 : //
9 : // Official repository: https://github.com/cppalliance/corosio
10 : //
11 :
12 : #ifndef BOOST_COROSIO_IO_IO_STREAM_HPP
13 : #define BOOST_COROSIO_IO_IO_STREAM_HPP
14 :
15 : #include <boost/corosio/detail/config.hpp>
16 : #include <boost/corosio/io/io_read_stream.hpp>
17 : #include <boost/corosio/io/io_write_stream.hpp>
18 : #include <boost/corosio/detail/buffer_param.hpp>
19 : #include <boost/capy/ex/executor_ref.hpp>
20 :
21 : #include <boost/capy/continuation.hpp>
22 :
23 : #include <coroutine>
24 : #include <cstddef>
25 : #include <stop_token>
26 : #include <system_error>
27 :
28 : namespace boost::corosio {
29 :
30 : /** Reads and writes bytes through a platform I/O backend.
31 :
32 : Combines @ref io_read_stream and @ref io_write_stream into
33 : a single bidirectional stream. The `read_some` and `write_some`
34 : operations are inherited from the base classes and dispatch through
35 : `do_read_some` / `do_write_some`. This class implements those by
36 : forwarding to the platform `implementation`.
37 :
38 : The implementation hierarchy stays linear (no diamond):
39 : `io_object::implementation` -> `io_stream::implementation`
40 : -> `tcp_socket::implementation` -> backend impl.
41 :
42 : @par Semantics
43 : Concrete classes wrap direct platform I/O completed by the kernel.
44 : Functions taking `io_stream&` signal that platform implementation
45 : is required. Use this when you need actual kernel I/O rather than
46 : a mock or test double.
47 :
48 : For generic stream algorithms that work with test mocks,
49 : use `template<capy::Stream S>` instead of `io_stream&`.
50 :
51 : @par Thread Safety
52 : Distinct objects: Safe.
53 : Shared objects: Unsafe. All calls to a single stream must be made
54 : from the same implicit or explicit serialization context.
55 :
56 : @par Example
57 : @par !example io_stream
58 :
59 : @see io_read_stream, io_write_stream, tcp_socket
60 : */
61 : class BOOST_COROSIO_DECL io_stream
62 : : public io_read_stream
63 : , public io_write_stream
64 : {
65 : public:
66 : /** Declares the read and write operations a platform backend
67 : must implement.
68 :
69 : Derived classes implement this interface to provide kernel-level
70 : read and write operations for each supported platform (IOCP,
71 : epoll, kqueue, io_uring).
72 : */
73 : struct implementation : io_object::implementation
74 : {
75 : /** Initiate platform read operation.
76 :
77 : @param cont Continuation to resume on completion; it lives in
78 : the awaiting frame until then.
79 : @param ex Executor for dispatching the completion.
80 : @param buffers Target buffer sequence.
81 : @param token Stop token for cancellation.
82 : @param ec Output error code.
83 : @param bytes Output bytes transferred.
84 :
85 : @return Coroutine handle to resume immediately.
86 : */
87 : virtual std::coroutine_handle<> read_some(
88 : capy::continuation& cont,
89 : capy::executor_ref ex,
90 : buffer_param buffers,
91 : std::stop_token token,
92 : std::error_code* ec,
93 : std::size_t* bytes) = 0;
94 :
95 : /** Initiate platform write operation.
96 :
97 : @param cont Continuation to resume on completion; it lives in
98 : the awaiting frame until then.
99 : @param ex Executor for dispatching the completion.
100 : @param buffers Source buffer sequence.
101 : @param token Stop token for cancellation.
102 : @param ec Output error code.
103 : @param bytes Output bytes transferred.
104 :
105 : @return Coroutine handle to resume immediately.
106 : */
107 : virtual std::coroutine_handle<> write_some(
108 : capy::continuation& cont,
109 : capy::executor_ref ex,
110 : buffer_param buffers,
111 : std::stop_token token,
112 : std::error_code* ec,
113 : std::size_t* bytes) = 0;
114 : };
115 :
116 : protected:
117 : /// Default construct; the handle is supplied through @ref io_object.
118 HIT 26592 : io_stream() noexcept = default;
119 :
120 : /// Construct stream from a handle.
121 : explicit io_stream(handle h) noexcept : io_object(std::move(h)) {}
122 :
123 : /** Dispatch read through implementation vtable.
124 :
125 : @param cont Continuation to resume on completion; it lives in
126 : the awaiting frame until then.
127 : @param ex Executor for dispatching the completion.
128 : @param buffers Target buffer sequence.
129 : @param token Stop token for cancellation.
130 : @param ec Output error code.
131 : @param bytes Output bytes transferred.
132 :
133 : @return Coroutine handle to resume immediately.
134 : */
135 238184 : std::coroutine_handle<> do_read_some(
136 : capy::continuation& cont,
137 : capy::executor_ref ex,
138 : buffer_param buffers,
139 : std::stop_token token,
140 : std::error_code* ec,
141 : std::size_t* bytes) override
142 : {
143 238184 : return get().read_some(cont, ex, buffers, std::move(token), ec, bytes);
144 : }
145 :
146 : /** Dispatch write through implementation vtable.
147 :
148 : @param cont Continuation to resume on completion; it lives in
149 : the awaiting frame until then.
150 : @param ex Executor for dispatching the completion.
151 : @param buffers Source buffer sequence.
152 : @param token Stop token for cancellation.
153 : @param ec Output error code.
154 : @param bytes Output bytes transferred.
155 :
156 : @return Coroutine handle to resume immediately.
157 : */
158 236452 : std::coroutine_handle<> do_write_some(
159 : capy::continuation& cont,
160 : capy::executor_ref ex,
161 : buffer_param buffers,
162 : std::stop_token token,
163 : std::error_code* ec,
164 : std::size_t* bytes) override
165 : {
166 236452 : return get().write_some(cont, ex, buffers, std::move(token), ec, bytes);
167 : }
168 :
169 : private:
170 : /// Return implementation downcasted to stream interface.
171 474636 : implementation& get() const noexcept
172 : {
173 474636 : return *static_cast<implementation*>(h_.get());
174 : }
175 : };
176 :
177 : } // namespace boost::corosio
178 :
179 : #endif
|