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 <coroutine>
22 : #include <cstddef>
23 : #include <stop_token>
24 : #include <system_error>
25 :
26 : namespace boost::corosio {
27 :
28 : /** Platform stream with read/write operations.
29 :
30 : Combines @ref io_read_stream and @ref io_write_stream into
31 : a single bidirectional stream. The `read_some` and `write_some`
32 : operations are inherited from the base classes and dispatch
33 : through `do_read_some` / `do_write_some`, which this class
34 : implements by forwarding to the platform `implementation`.
35 :
36 : The implementation hierarchy stays linear (no diamond):
37 : `io_object::implementation` -> `io_stream::implementation`
38 : -> `tcp_socket::implementation` -> backend impl.
39 :
40 : @par Semantics
41 : Concrete classes wrap direct platform I/O completed by the kernel.
42 : Functions taking `io_stream&` signal "platform implementation
43 : required" - use this when you need actual kernel I/O rather than
44 : a mock or test double.
45 :
46 : For generic stream algorithms that work with test mocks,
47 : use `template<capy::Stream S>` instead of `io_stream&`.
48 :
49 : @par Thread Safety
50 : Distinct objects: Safe.
51 : Shared objects: Unsafe. All calls to a single stream must be made
52 : from the same implicit or explicit serialization context.
53 :
54 : @par Example
55 : @par !example io_stream
56 :
57 : @see io_read_stream, io_write_stream, tcp_socket
58 : */
59 : class BOOST_COROSIO_DECL io_stream
60 : : public io_read_stream
61 : , public io_write_stream
62 : {
63 : public:
64 : /** Platform-specific stream implementation interface.
65 :
66 : Derived classes implement this interface to provide kernel-level
67 : read and write operations for each supported platform (IOCP,
68 : epoll, kqueue, io_uring).
69 : */
70 : struct implementation : io_object::implementation
71 : {
72 : /// Initiate platform read operation.
73 : virtual std::coroutine_handle<> read_some(
74 : std::coroutine_handle<>,
75 : capy::executor_ref,
76 : buffer_param,
77 : std::stop_token,
78 : std::error_code*,
79 : std::size_t*) = 0;
80 :
81 : /// Initiate platform write operation.
82 : virtual std::coroutine_handle<> write_some(
83 : std::coroutine_handle<>,
84 : capy::executor_ref,
85 : buffer_param,
86 : std::stop_token,
87 : std::error_code*,
88 : std::size_t*) = 0;
89 : };
90 :
91 : protected:
92 HIT 10480 : io_stream() noexcept = default;
93 :
94 : /// Construct stream from a handle.
95 : explicit io_stream(handle h) noexcept : io_object(std::move(h)) {}
96 :
97 : /// Dispatch read through implementation vtable.
98 203131 : std::coroutine_handle<> do_read_some(
99 : std::coroutine_handle<> h,
100 : capy::executor_ref ex,
101 : buffer_param buffers,
102 : std::stop_token token,
103 : std::error_code* ec,
104 : std::size_t* bytes) override
105 : {
106 203131 : return get().read_some(h, ex, buffers, std::move(token), ec, bytes);
107 : }
108 :
109 : /// Dispatch write through implementation vtable.
110 202386 : std::coroutine_handle<> do_write_some(
111 : std::coroutine_handle<> h,
112 : capy::executor_ref ex,
113 : buffer_param buffers,
114 : std::stop_token token,
115 : std::error_code* ec,
116 : std::size_t* bytes) override
117 : {
118 202386 : return get().write_some(h, ex, buffers, std::move(token), ec, bytes);
119 : }
120 :
121 : private:
122 : /// Return implementation downcasted to stream interface.
123 405517 : implementation& get() const noexcept
124 : {
125 405517 : return *static_cast<implementation*>(h_.get());
126 : }
127 : };
128 :
129 : } // namespace boost::corosio
130 :
131 : #endif
|