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