Skip to content

Commit 5315943

Browse files
authored
Add more documentation for stream.{read,write}. (#541)
Notably: - Document what stream.{read,write} do after a `copy-result.dropped`, similar to what is documented for future.{read,write}. - Document that `copy-result.dropped` does not signify an error. - Reword "the only valid next operation is" to "anything subsequent operation [...] traps" to avoid confusion about what "valid" means in this context. - Say "single-element" instead of "length-1" so that it doesn't risk scanning as "length minus one".
1 parent 2d915e3 commit 5315943

File tree

2 files changed

+37
-17
lines changed

2 files changed

+37
-17
lines changed

design/mvp/CanonicalABI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3897,7 +3897,7 @@ ownership of `buffer` and prevent any further partial reads/writes. Thus, up
38973897
until event delivery, the other end of the stream is free to repeatedly
38983898
read/write from/to `buffer`, ideally filling it up and minimizing context
38993899
switches. Next, `copying` is cleared to reenable future `stream.{read,write}`
3900-
calls. However, if the `CopyResult` is `DROPPED`, `dropped` is set to disallow
3900+
calls. However, if the `CopyResult` is `DROPPED`, `done` is set to disallow
39013901
all future use of this stream end. Lastly, `stream_event` packs the
39023902
`CopyResult` and number of elements copied up until this point into a single
39033903
`i32` payload for core wasm.

design/mvp/Explainer.md

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,18 +1798,31 @@ An analogous relationship exists among `readable-future-end<T?>`,
17981798
where `stream-result` is defined in WIT as:
17991799
```wit
18001800
record stream-result {
1801-
progress: u32,
1802-
result: copy-result
1801+
/// The number of elements read/written.
1802+
progress: u32,
1803+
1804+
/// The status of the read/write operation.
1805+
result: copy-result
18031806
}
18041807
18051808
enum copy-result {
1806-
// The read/write completed successfully and is ready for more.
1809+
/// The read/write completed successfully.
1810+
///
1811+
/// The stream remains open for new reads/writes.
18071812
completed,
18081813
1809-
// The other end was dropped and so this end must now be dropped.
1814+
/// The other end was dropped and so this end must now be dropped.
1815+
///
1816+
/// For `stream.read`, this means that the end of the stream was reached.
1817+
///
1818+
/// For `stream.write`, this means that the consumer has no need for further
1819+
/// data from this stream. This doesn't signify an error; it just instructs
1820+
/// the producer to stop sending data.
18101821
dropped,
18111822
1812-
// The read/write was cancelled by stream.cancel-{read,write}; future reads/writes are possible.
1823+
/// The read/write was cancelled by `stream.cancel-{read,write}`.
1824+
///
1825+
/// The stream remains open for new reads/writes.
18131826
cancelled
18141827
}
18151828
```
@@ -1824,14 +1837,17 @@ many `T` elements were read or written from the given buffer before the
18241837
`copy-result` was reached. For example, a return value of `{progress: 4,
18251838
result: dropped}` from a `stream<u32>.read` means that 32 bytes were copied
18261839
into the given buffer before the writer end dropped the stream. The `cancelled`
1827-
case can only arise as the result of a call to `stream.cancel-{read,write}`
1828-
and is included in `copy-result` because it is reused below.
1840+
case can only arise as the result of a call to `stream.cancel-{read,write}`.
18291841

18301842
If the return value is `none`, then the operation blocked and the caller needs
18311843
to [wait](Async.md#waiting) for progress (via `waitable-set.{wait,poll}` or, if
18321844
using a `callback`, by returning to the event loop) which will asynchronously
18331845
produce an `event` containing a `stream-result`.
18341846

1847+
If `stream.{read,write}` return `dropped` (synchronously or asynchronously),
1848+
any subsequent operation on the stream other than `stream.drop-{readable,writable}`
1849+
traps.
1850+
18351851
In the Canonical ABI, the `{readable,writable}-stream-end` is passed as an
18361852
`i32` index into the component instance's table followed by a pair of `i32`s
18371853
describing the linear memory offset and size-in-elements of the
@@ -1854,20 +1870,24 @@ bit-packed into a single `i32` where:
18541870
where `future-{read,write}-result` are defined in WIT as:
18551871
```wit
18561872
enum future-read-result {
1857-
// The read completed and this readable end must now be dropped.
1873+
/// The read completed and this readable end must now be dropped.
18581874
completed,
18591875
1860-
// The read was cancelled by future.cancel-read; future reads are possible.
1876+
/// The read was cancelled by `future.cancel-read`.
1877+
///
1878+
/// The future remains open for a new `future.read`.
18611879
cancelled
18621880
}
18631881
enum future-write-result {
1864-
// The write completed successfully and this writable end must now be dropped.
1882+
/// The write completed successfully and this writable end must now be dropped.
18651883
completed,
18661884
1867-
// The readable end was dropped and so the writable end must now be dropped.
1885+
/// The readable end was dropped and so the writable end must now be dropped.
18681886
dropped,
18691887
1870-
// The write was cancelled by future.cancel-write; future writes are possible.
1888+
/// The write was cancelled by `future.cancel-write`.
1889+
///
1890+
/// The future remains open for a new `future.write`.
18711891
cancelled
18721892
}
18731893
```
@@ -1878,17 +1898,17 @@ to drop their end before writing a value). `future-write-result` is the same as
18781898
that the reader signalled loss of interest by dropping their end).
18791899

18801900
The `future.{read,write}` built-ins takes the [readable or writable end] of a
1881-
future as the first parameter and, if `T` is present, a length-1 buffer that
1882-
can be used to write or read a single `T` value.
1901+
future as the first parameter and, if `T` is present, a single-element buffer
1902+
that can be used to write or read a single `T` value.
18831903

18841904
If the return value is `none`, then the call blocked and the caller needs
18851905
to [wait](Async.md#waiting) for progress (via `waitable-set.{wait,poll}` or, if
18861906
using a `callback`, by returning to the event loop) which will asynchronously
18871907
produce an `event` containing a `future-{read,write}-result`.
18881908

18891909
If `future.{read,write}` return `completed` or `dropped` (synchronously or
1890-
asynchronously), the only valid next operation is
1891-
`future.drop-{readable,writable}`.
1910+
asynchronously), any subsequent operation on the future other than
1911+
`future.drop-{readable,writable}` traps.
18921912

18931913
A component *may* call `future.drop-readable` *before* successfully reading a
18941914
value to indicate a loss of interest. `future.drop-writable` will trap if

0 commit comments

Comments
 (0)