TLA Line data Source code
1 : //
2 : // Copyright (c) 2026 Steve Gerbino
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/cppalliance/corosio
8 : //
9 :
10 : #ifndef BOOST_COROSIO_IO_IO_WRITE_STREAM_HPP
11 : #define BOOST_COROSIO_IO_IO_WRITE_STREAM_HPP
12 :
13 : #include <boost/corosio/detail/config.hpp>
14 : #include <boost/corosio/detail/op_base.hpp>
15 : #include <boost/corosio/io/io_object.hpp>
16 : #include <boost/corosio/detail/buffer_param.hpp>
17 : #include <boost/capy/io_result.hpp>
18 : #include <boost/capy/ex/executor_ref.hpp>
19 : #include <boost/capy/ex/io_env.hpp>
20 :
21 : #include <coroutine>
22 : #include <cstddef>
23 : #include <stop_token>
24 : #include <system_error>
25 :
26 : namespace boost::corosio {
27 :
28 : /** Abstract base for streams that support async writes.
29 :
30 : Provides the `write_some` operation via a pure virtual
31 : `do_write_some` dispatch point. Concrete classes override
32 : `do_write_some` to route through their implementation.
33 :
34 : Uses virtual inheritance from @ref io_object so that
35 : @ref io_stream can combine this with @ref io_read_stream
36 : without duplicating the `io_object` base.
37 :
38 : @par Thread Safety
39 : Distinct objects: Safe.
40 : Shared objects: Unsafe.
41 :
42 : @see io_read_stream, io_stream, io_object
43 : */
44 : class BOOST_COROSIO_DECL io_write_stream : virtual public io_object
45 : {
46 : protected:
47 : /// Awaitable for async write operations.
48 : template<class ConstBufferSequence>
49 : struct write_some_awaitable
50 : : detail::bytes_op_base<write_some_awaitable<ConstBufferSequence>>
51 : {
52 : io_write_stream& ios_;
53 : ConstBufferSequence buffers_;
54 :
55 HIT 202912 : write_some_awaitable(
56 : io_write_stream& ios, ConstBufferSequence buffers) noexcept
57 202912 : : ios_(ios), buffers_(std::move(buffers)) {}
58 :
59 202912 : std::coroutine_handle<> dispatch(
60 : std::coroutine_handle<> h, capy::executor_ref ex) const
61 : {
62 405824 : return ios_.do_write_some(
63 608736 : h, ex, buffers_, this->token_, &this->ec_, &this->bytes_);
64 : }
65 : };
66 :
67 : /** Dispatch a write through the concrete implementation.
68 :
69 : @param h Coroutine handle to resume on completion.
70 : @param ex Executor for dispatching the completion.
71 : @param buffers Source buffer sequence.
72 : @param token Stop token for cancellation.
73 : @param ec Output error code.
74 : @param bytes Output bytes transferred.
75 :
76 : @return Coroutine handle to resume immediately.
77 : */
78 : virtual std::coroutine_handle<> do_write_some(
79 : std::coroutine_handle<>,
80 : capy::executor_ref,
81 : buffer_param,
82 : std::stop_token,
83 : std::error_code*,
84 : std::size_t*) = 0;
85 :
86 17384 : io_write_stream() noexcept = default;
87 :
88 : /// Construct from a handle.
89 : explicit io_write_stream(handle h) noexcept : io_object(std::move(h)) {}
90 :
91 : io_write_stream(io_write_stream&&) noexcept = default;
92 : io_write_stream& operator=(io_write_stream&&) noexcept = delete;
93 : io_write_stream(io_write_stream const&) = delete;
94 : io_write_stream& operator=(io_write_stream const&) = delete;
95 :
96 : public:
97 : /** Asynchronously write data to the stream.
98 :
99 : Suspends the calling coroutine and initiates a kernel-level
100 : write. The coroutine resumes when at least one byte is written,
101 : an error occurs, or the operation is cancelled.
102 :
103 : This stream must outlive the returned awaitable. The memory
104 : referenced by @p buffers must remain valid until the operation
105 : completes.
106 :
107 : @param buffers The buffer sequence containing data to write.
108 :
109 : @return An awaitable yielding `(error_code, std::size_t)`.
110 :
111 : @see io_stream::read_some
112 : */
113 : template<capy::ConstBufferSequence CB>
114 202912 : auto write_some(CB const& buffers)
115 : {
116 202912 : return write_some_awaitable<CB>(*this, buffers);
117 : }
118 : };
119 :
120 : } // namespace boost::corosio
121 :
122 : #endif
|