@@ -134,58 +134,115 @@ interface streams {
134134 /// This [represents a resource](https://github.com/WebAssembly/WASI/blob/main/docs/WitInWasi.md#Resources).
135135 type output-stream = u32
136136
137- /// Perform a non-blocking write of bytes to a stream.
137+ /// An error for output- stream operations .
138138 ///
139- /// This function returns a `u64` and a `stream-status` . The `u64` indicates
140- /// the number of bytes from `buf` that were written, which may be less than
141- /// the length of `buf` . The `stream-status` indicates if further writes to
142- /// the stream are expected to be read.
139+ /// Contrary to input-streams, a closed output-stream is reported using
140+ /// an error.
141+ enum write-error {
142+ /// The last operation (a write or flush) failed before completion.
143+ last-operation-failed ,
144+ /// The stream is closed: no more input will be accepted by the
145+ /// stream. A closed output-stream will return this error on all
146+ /// future operations.
147+ closed
148+ }
149+ /// Check readiness for writing. This function never blocks.
150+ ///
151+ /// Returns the number of bytes permitted for the next call to `write` ,
152+ /// or an error. Calling `write` with more bytes than this function has
153+ /// permitted will trap.
154+ ///
155+ /// When this function returns 0 bytes, the `subscribe-to-output-stream`
156+ /// pollable will become ready when this function will report at least
157+ /// 1 byte, or an error.
158+ check-write : func (
159+ this : output-stream
160+ ) -> result <u64 , write-error >
161+
162+ /// Perform a write. This function never blocks.
143163 ///
144- /// When the returned `stream-status` is `open` , the `u64` return value may
145- /// be less than the length of `buf` . This indicates that no more bytes may
146- /// be written to the stream promptly. In that case the
147- /// `subscribe-to-output-stream` pollable will indicate when additional bytes
148- /// may be promptly written.
164+ /// Precondition: check-write gave permit of Ok(n) and contents has a
165+ /// length of less than or equal to n. Otherwise, this function will trap.
149166 ///
150- /// Writing an empty list must return a non-error result with `0` for the
151- /// `u64` return value, and the current `stream-status` .
167+ /// returns Err(closed) without writing if the stream has closed since
168+ /// the last call to check-write provided a permit .
152169 write : func (
153170 this : output-stream ,
154- /// Data to write
155- buf : list <u8 >
156- ) -> result <tuple <u64 , stream-status >>
171+ contents : list <u8 >
172+ ) -> result <_ , write-error >
157173
158- /// Blocking write of bytes to a stream.
174+ /// Perform a write of up to 4096 bytes, and then flush the stream. Block
175+ /// until all of these operations are complete, or an error occurs.
159176 ///
160- /// This is similar to `write` , except that it blocks until at least one
161- /// byte can be written.
162- blocking-write : func (
163- this : output-stream ,
164- /// Data to write
165- buf : list <u8 >
166- ) -> result <tuple <u64 , stream-status >>
177+ /// This is a convenience wrapper around the use of `check-write` ,
178+ /// `subscribe-to-output-stream` , `write` , and `flush` , and is implemented
179+ /// with the following pseudo-code:
180+ ///
181+ /// `` `text
182+ /// let pollable = subscribe-to-output-stream(this);
183+ /// while !contents.is_empty() {
184+ /// // Wait for the stream to become writable
185+ /// poll-oneoff(pollable);
186+ /// let Ok(n) = check-write(this); // eliding error handling
187+ /// let len = min(n, contents.len());
188+ /// let (chunk, rest) = contents.split_at(len);
189+ /// write(this, chunk); // eliding error handling
190+ /// contents = rest;
191+ /// }
192+ /// flush(this);
193+ /// // Wait for completion of `flush`
194+ /// poll-oneoff(pollable);
195+ /// // Check for any errors that arose during `flush`
196+ /// let _ = check-write(this); // eliding error handling
197+ /// `` `
198+ blocking-write-and-flush : func (
199+ this : output-stream ,
200+ contents : list <u8 >
201+ ) -> result <_ , write-error >
167202
168- /// Write multiple zero-bytes to a stream .
203+ /// Request to flush buffered output. This function never blocks .
169204 ///
170- /// This function returns a `u64` indicating the number of zero-bytes
171- /// that were written; it may be less than `len` . Equivelant to a call to
172- /// `write` with a list of zeroes of the given length.
173- write-zeroes : func (
205+ /// This tells the output-stream that the caller intends any buffered
206+ /// output to be flushed. the output which is expected to be flushed
207+ /// is all that has been passed to `write` prior to this call.
208+ ///
209+ /// Upon calling this function, the `output-stream` will not accept any
210+ /// writes (`check-write` will return `ok(0)` ) until the flush has
211+ /// completed. The `subscribe-to-output-stream` pollable will become ready
212+ /// when the flush has completed and the stream can accept more writes.
213+ flush : func (
174214 this : output-stream ,
175- /// The number of zero-bytes to write
176- len : u64
177- ) -> result <tuple <u64 , stream-status >>
215+ ) -> result <_ , write-error >
216+
217+ /// Request to flush buffered output, and block until flush completes
218+ /// and stream is ready for writing again.
219+ blocking-flush : func (
220+ this : output-stream ,
221+ ) -> result <_ , write-error >
222+
223+ /// Create a `pollable` which will resolve once the output-stream
224+ /// is ready for more writing, or an error has occured. When this
225+ /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an
226+ /// error.
227+ ///
228+ /// If the stream is closed, this pollable is always ready immediately.
229+ ///
230+ /// The created `pollable` is a child resource of the `output-stream` .
231+ /// Implementations may trap if the `output-stream` is dropped before
232+ /// all derived `pollable` s created with this function are dropped.
233+ subscribe-to-output-stream : func (this : output-stream ) -> pollable
178234
179- /// Write multiple zero bytes to a stream, with blocking .
235+ /// Write zeroes to a stream.
180236 ///
181- /// This is similar to `write-zeroes` , except that it blocks until at least
182- /// one byte can be written. Equivelant to a call to `blocking-write` with
183- /// a list of zeroes of the given length.
184- blocking-write-zeroes : func (
237+ /// this should be used precisely like `write` with the exact same
238+ /// preconditions (must use check-write first), but instead of
239+ /// passing a list of bytes, you simply pass the number of zero-bytes
240+ /// that should be written.
241+ write-zeroes : func (
185242 this : output-stream ,
186- /// The number of zero bytes to write
243+ /// The number of zero- bytes to write
187244 len : u64
188- ) -> result <tuple < u64 , stream-status > >
245+ ) -> result <_ , write-error >
189246
190247 /// Read from one stream and write to another.
191248 ///
@@ -232,16 +289,6 @@ interface streams {
232289 src : input-stream
233290 ) -> result <tuple <u64 , stream-status >>
234291
235- /// Create a `pollable` which will resolve once either the specified stream
236- /// is ready to accept bytes or the `stream-state` has become closed.
237- ///
238- /// Once the stream-state is closed, this pollable is always ready
239- /// immediately.
240- ///
241- /// The created `pollable` is a child resource of the `output-stream` .
242- /// Implementations may trap if the `output-stream` is dropped before
243- /// all derived `pollable` s created with this function are dropped.
244- subscribe-to-output-stream : func (this : output-stream ) -> pollable
245292
246293 /// Dispose of the specified `output-stream` , after which it may no longer
247294 /// be used.
0 commit comments