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/results.hpp>
18 : #include <boost/capy/ex/executor_ref.hpp>
19 : #include <boost/capy/ex/await_context.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 : /** Writes bytes to a stream asynchronously.
31 :
32 : Provides the `write_some` operation via a pure virtual
33 : `do_write_some` dispatch point. Concrete classes override
34 : `do_write_some` to route through their implementation.
35 :
36 : Uses virtual inheritance from @ref io_object so that
37 : @ref io_stream can combine this with @ref io_read_stream
38 : without duplicating the `io_object` base.
39 :
40 : @par Thread Safety
41 : Distinct objects: Safe.
42 : Shared objects: Unsafe.
43 :
44 : @see io_read_stream, io_stream, io_object
45 : */
46 : class BOOST_COROSIO_DECL io_write_stream : virtual public io_object
47 : {
48 : protected:
49 : /// Awaitable for async write operations.
50 : template<class ConstBufferSequence>
51 : struct write_some_awaitable
52 : : detail::bytes_op_base<write_some_awaitable<ConstBufferSequence>>
53 : {
54 : private:
55 : friend io_write_stream;
56 :
57 HIT 236483 : write_some_awaitable(
58 : io_write_stream& ios, ConstBufferSequence buffers) noexcept
59 236483 : : ios_(ios)
60 236483 : , buffers_(std::move(buffers))
61 : {
62 236483 : }
63 :
64 : friend detail::bytes_op_base<write_some_awaitable<ConstBufferSequence>>;
65 : io_write_stream& ios_;
66 : ConstBufferSequence buffers_;
67 :
68 : std::coroutine_handle<>
69 236452 : dispatch(capy::continuation& cont, capy::executor_ref ex) const
70 : {
71 472904 : return ios_.do_write_some(
72 709356 : cont, ex, buffers_, this->token_, &this->ec_, &this->bytes_);
73 : }
74 : };
75 :
76 : /** Dispatch a write through the concrete implementation.
77 :
78 : @param cont Continuation to resume on completion; it lives in
79 : the awaiting frame until then.
80 : @param ex Executor for dispatching the completion.
81 : @param buffers Source buffer sequence.
82 : @param token Stop token for cancellation.
83 : @param ec Output error code.
84 : @param bytes Output bytes transferred.
85 :
86 : @return Coroutine handle to resume immediately.
87 : */
88 : virtual std::coroutine_handle<> do_write_some(
89 : capy::continuation& cont,
90 : capy::executor_ref ex,
91 : buffer_param buffers,
92 : std::stop_token token,
93 : std::error_code* ec,
94 : std::size_t* bytes) = 0;
95 :
96 : /// Default construct; the handle is supplied through @ref io_object.
97 26592 : io_write_stream() noexcept = default;
98 :
99 : /// Move construct; the handle moves with @ref io_object.
100 : io_write_stream(io_write_stream&&) noexcept = default;
101 : /// Move assignment is disabled; reseating a live stream is not supported.
102 : io_write_stream& operator=(io_write_stream&&) noexcept = delete;
103 : /// Copy construction is disabled; the handle is uniquely owned.
104 : io_write_stream(io_write_stream const&) = delete;
105 : /// Copy assignment is disabled; the handle is uniquely owned.
106 : io_write_stream& operator=(io_write_stream const&) = delete;
107 :
108 : public:
109 : /** Asynchronously write data to the stream.
110 :
111 : Suspends the calling coroutine and initiates a kernel-level
112 : write. The coroutine resumes when at least one byte is written,
113 : an error occurs, or the operation is cancelled.
114 :
115 : This stream must outlive the returned awaitable. The memory
116 : referenced by @p buffers must remain valid until the operation
117 : completes.
118 :
119 : A closed stream completes with `errc::bad_file_descriptor`.
120 :
121 : @param buffers The buffer sequence containing data to write.
122 :
123 : @return An awaitable yielding `(error_code, std::size_t)`.
124 :
125 : @see io_stream::read_some
126 : */
127 : template<capy::ConstBufferSequence CB>
128 236483 : [[nodiscard]] auto write_some(CB const& buffers)
129 : {
130 236483 : return write_some_awaitable<CB>(*this, buffers);
131 : }
132 : };
133 :
134 : } // namespace boost::corosio
135 :
136 : #endif
|