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   /** Platform stream with read/write operations. 28   /** Platform stream with read/write operations.
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 32   operations are inherited from the base classes and dispatch
33   through `do_read_some` / `do_write_some`, which this class 33   through `do_read_some` / `do_write_some`, which this class
34   implements by forwarding to the platform `implementation`. 34   implements by 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 "platform implementation 42   Functions taking `io_stream&` signal "platform implementation
43   required" - use this when you need actual kernel I/O rather than 43   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   /** Platform-specific stream implementation interface. 64   /** Platform-specific stream implementation interface.
65   65  
66   Derived classes implement this interface to provide kernel-level 66   Derived classes implement this interface to provide kernel-level
67   read and write operations for each supported platform (IOCP, 67   read and write operations for each supported platform (IOCP,
68   epoll, kqueue, io_uring). 68   epoll, kqueue, io_uring).
69   */ 69   */
70   struct implementation : io_object::implementation 70   struct implementation : io_object::implementation
71   { 71   {
72   /// Initiate platform read operation. 72   /// Initiate platform read operation.
73   virtual std::coroutine_handle<> read_some( 73   virtual std::coroutine_handle<> read_some(
74   std::coroutine_handle<>, 74   std::coroutine_handle<>,
75   capy::executor_ref, 75   capy::executor_ref,
76   buffer_param, 76   buffer_param,
77   std::stop_token, 77   std::stop_token,
78   std::error_code*, 78   std::error_code*,
79   std::size_t*) = 0; 79   std::size_t*) = 0;
80   80  
81   /// Initiate platform write operation. 81   /// Initiate platform write operation.
82   virtual std::coroutine_handle<> write_some( 82   virtual std::coroutine_handle<> write_some(
83   std::coroutine_handle<>, 83   std::coroutine_handle<>,
84   capy::executor_ref, 84   capy::executor_ref,
85   buffer_param, 85   buffer_param,
86   std::stop_token, 86   std::stop_token,
87   std::error_code*, 87   std::error_code*,
88   std::size_t*) = 0; 88   std::size_t*) = 0;
89   }; 89   };
90   90  
91   protected: 91   protected:
HITCBC 92   10438 io_stream() noexcept = default; 92   10480 io_stream() noexcept = default;
93   93  
94   /// Construct stream from a handle. 94   /// Construct stream from a handle.
95   explicit io_stream(handle h) noexcept : io_object(std::move(h)) {} 95   explicit io_stream(handle h) noexcept : io_object(std::move(h)) {}
96   96  
97   /// Dispatch read through implementation vtable. 97   /// Dispatch read through implementation vtable.
HITCBC 98   221650 std::coroutine_handle<> do_read_some( 98   203131 std::coroutine_handle<> do_read_some(
99   std::coroutine_handle<> h, 99   std::coroutine_handle<> h,
100   capy::executor_ref ex, 100   capy::executor_ref ex,
101   buffer_param buffers, 101   buffer_param buffers,
102   std::stop_token token, 102   std::stop_token token,
103   std::error_code* ec, 103   std::error_code* ec,
104   std::size_t* bytes) override 104   std::size_t* bytes) override
105   { 105   {
HITCBC 106   221650 return get().read_some(h, ex, buffers, std::move(token), ec, bytes); 106   203131 return get().read_some(h, ex, buffers, std::move(token), ec, bytes);
107   } 107   }
108   108  
109   /// Dispatch write through implementation vtable. 109   /// Dispatch write through implementation vtable.
HITCBC 110   220905 std::coroutine_handle<> do_write_some( 110   202386 std::coroutine_handle<> do_write_some(
111   std::coroutine_handle<> h, 111   std::coroutine_handle<> h,
112   capy::executor_ref ex, 112   capy::executor_ref ex,
113   buffer_param buffers, 113   buffer_param buffers,
114   std::stop_token token, 114   std::stop_token token,
115   std::error_code* ec, 115   std::error_code* ec,
116   std::size_t* bytes) override 116   std::size_t* bytes) override
117   { 117   {
HITCBC 118   220905 return get().write_some(h, ex, buffers, std::move(token), ec, bytes); 118   202386 return get().write_some(h, ex, buffers, std::move(token), ec, bytes);
119   } 119   }
120   120  
121   private: 121   private:
122   /// Return implementation downcasted to stream interface. 122   /// Return implementation downcasted to stream interface.
HITCBC 123   442555 implementation& get() const noexcept 123   405517 implementation& get() const noexcept
124   { 124   {
HITCBC 125   442555 return *static_cast<implementation*>(h_.get()); 125   405517 return *static_cast<implementation*>(h_.get());
126   } 126   }
127   }; 127   };
128   128  
129   } // namespace boost::corosio 129   } // namespace boost::corosio
130   130  
131   #endif 131   #endif