@@ -318,13 +318,10 @@ a `stream` or `future` somewhere in the parameter types) or result (of an
318
318
import call with a ` stream ` or ` future ` somewhere in the result type), the
319
319
receiver always gets * unique ownership* of the * readable end* of the ` stream `
320
320
or ` future ` . When * producing* a ` stream ` or ` future ` value as a parameter (of
321
- an import call) or result (of an export call), the producer can either
322
- * transfer ownership* of a readable end it has already received or it can create
323
- a fresh writable end (via ` stream.new ` or ` future.new ` ) and then lift this
324
- writable end to create a fresh readable end in the consumer while maintaining
325
- ownership of the writable end in the producer. To maintain the invariant that
326
- readable ends are unique, a writable end can be lifted at most once, trapping
327
- otherwise.
321
+ an import call) or result (of an export call), the producer can * transfer
322
+ ownership* of a readable end that it has either been given by the outside world
323
+ or freshly created via ` {stream,future}.new ` (which also return a fresh paired
324
+ writable end that is permanently owned by the calling component instance).
328
325
329
326
Based on this, ` stream<T> ` and ` future<T> ` values can be passed between
330
327
functions as if they were synchronous ` list<T> ` and ` T ` values, resp. For
@@ -339,16 +336,6 @@ its returned `stream<T>` with an [`error-context`](Explainer.md#error-context-ty
339
336
value which ` g ` will receive along with the notification that its readable
340
337
stream was closed.
341
338
342
- If a component instance * would* receive the readable end of a stream for which
343
- it already owns the writable end, the readable end disappears and the existing
344
- writable end is received instead (since the guest can now handle the whole
345
- stream more efficiently wholly from within guest code). E.g., if the same
346
- component instance defined ` f ` and ` g ` above, the composition ` g(f(x)) ` would
347
- just instruct the guest to stream directly from ` f ` into ` g ` without crossing a
348
- component boundary or performing any extra copies. Thus, strengthening the
349
- previously-mentioned invariant, the readable and writable ends of a stream are
350
- unique * and never in the same component* .
351
-
352
339
Given the readable or writable end of a stream, core wasm code can call the
353
340
imported ` stream.read ` or ` stream.write ` canonical built-ins, resp., passing the
354
341
pointer and length of a linear-memory buffer to write-into or read-from, resp.
@@ -358,6 +345,10 @@ value indicating that the read or write will execute concurrently. The readable
358
345
and writable ends of streams and futures can then be [ waited] ( #waiting ) on to
359
346
make progress.
360
347
348
+ As a temporary limitation, if a ` read ` and ` write ` for a single stream or
349
+ future occur from within the same component, there is a trap. In the future
350
+ this limitation will be removed.
351
+
361
352
The ` T ` element type of streams and futures is optional, such that ` future ` and
362
353
` stream ` can be written in WIT without a trailing ` <T> ` . In this case, the
363
354
asynchronous "values(s)" being delivered are effectively meaningless [ unit]
@@ -369,14 +360,6 @@ without requiring an explicit `future` return type. Thus, a function like
369
360
which point the caller receives the readable end of a ` future ` that, when
370
361
successfully read, conveys the completion of a second event.
371
362
372
- From a [ structured-concurrency] ( #structured-concurrency ) perspective, the
373
- readable and writable ends of streams and futures are leaves of the async call
374
- tree. Unlike subtasks, the parent of the readable ends of streams and future
375
- * can* change over time (when transferred via function call, as mentioned
376
- above). However, there is always * some* parent ` Task ` and this parent ` Task `
377
- is prevented from orphaning its children using the same reference-counting
378
- guard mentioned above for subtasks.
379
-
380
363
The [ Stream State] and [ Future State] sections describe the runtime state
381
364
maintained for streams and futures by the Canonical ABI.
382
365
@@ -928,6 +911,8 @@ Native async support is being proposed incrementally. The following features
928
911
will be added in future chunks roughly in the order listed to complete the full
929
912
"async" story, with a TBD cutoff between what's in [ WASI Preview 3] and what
930
913
comes after:
914
+ * remove the temporary trap mentioned above that occurs when a ` read ` and
915
+ ` write ` of a stream/future happen from within the same component instance
931
916
* ` subtask.cancel ` : allow a supertask to signal to a subtask that its result is
932
917
no longer wanted and to please wrap it up promptly
933
918
* zero-copy forwarding/splicing
0 commit comments