@@ -261,7 +261,7 @@ class ComponentInstance:
261
261
pending_async_tasks: list[asyncio.Future]
262
262
handles: HandleTables
263
263
async_subtasks: Table[AsyncSubtask]
264
- active : asyncio.Lock
264
+ fiber : asyncio.Lock
265
265
266
266
def __init__ (self ):
267
267
self .may_leave = True
@@ -271,7 +271,7 @@ class ComponentInstance:
271
271
self .pending_async_tasks = []
272
272
self .handles = HandleTables()
273
273
self .async_subtasks = Table[AsyncSubtask]()
274
- self .active = asyncio.Lock()
274
+ self .fiber = asyncio.Lock()
275
275
```
276
276
The ` may_leave ` field is used below to track whether the instance may call a
277
277
lowered import to prevent optimization-breaking cases of reentrance during
@@ -289,16 +289,16 @@ The `async_subtasks` field is used below to track and assign an `i32` index to
289
289
each active async-lowered call in progress that has been made by this
290
290
` ComponentInstance ` .
291
291
292
- Finally, the ` active ` field is used below to restrict the switching of Python
292
+ Finally, the ` fiber ` field is used below to restrict the switching of Python
293
293
coroutines (` async def ` functions) to only occur at specific points (such as
294
294
when a task blocks on ` task.wait ` or when an ` async callback ` -lifted export
295
295
call returns to its event loop to wait for an event. Thus, the calls to
296
- ` active .acquire()` and ` active .release()` in the Python code below point to
296
+ ` fiber .acquire()` and ` fiber .release()` in the Python code below point to
297
297
where the runtime may switch between concurrent tasks. Without this
298
298
` asyncio.Lock ` , Python's normal ` asyncio ` semantics would allow switching
299
299
between concurrent tasks at * every* spec-internal ` await ` , which would lead to
300
300
multi-threading-like interleaving between concurrent tasks. (Alternatively, if
301
- Python had standard-library fibers, they could have been used instead of
301
+ Python had standard-library [ fibers] , they could have been used instead of
302
302
` asyncio ` , obviating the need for this ` Lock ` .)
303
303
304
304
One ` HandleTables ` object is stored per ` ComponentInstance ` and is defined as:
@@ -495,12 +495,12 @@ for a component export called directly by the host, or else the current task
495
495
when the calling component called into this component. The ` caller ` field is
496
496
used by the following two methods to prevent a component from being reentered
497
497
(enforcing the [ component invariant] ) in a way that is well-defined even in the
498
- presence of async calls). (The ` active .acquire()` call in ` enter() ` is
498
+ presence of async calls). (The ` fiber .acquire()` call in ` enter() ` is
499
499
described above and here ensures that concurrent export calls do not
500
500
arbitrarily interleave.)
501
501
``` python
502
502
async def enter (self ):
503
- await self .inst.active .acquire()
503
+ await self .inst.fiber .acquire()
504
504
self .trap_if_on_the_stack(self .inst)
505
505
506
506
def trap_if_on_the_stack (self , inst ):
@@ -558,9 +558,9 @@ guarded to be `0` in `Task.exit` (below) to ensure [structured concurrency].
558
558
self .events.put_nowait(subtask)
559
559
560
560
async def wait (self ):
561
- self .inst.active .release()
561
+ self .inst.fiber .release()
562
562
subtask = await self .events.get()
563
- await self .inst.active .acquire()
563
+ await self .inst.fiber .acquire()
564
564
return self .process_event(subtask)
565
565
566
566
def process_event (self , subtask ):
@@ -579,7 +579,7 @@ should not have to create an actual queue; instead it should be possible to
579
579
embed a "next ready" linked list in the elements of the ` async_subtasks ` table
580
580
(noting the ` enqueued ` guard above ensures that a subtask can be enqueued at
581
581
most once). The implementation of ` wait ` releases and reacquires the
582
- instance-wide ` active ` lock to specify that ` wait ` is a point where the runtime
582
+ instance-wide ` fiber ` lock to specify that ` wait ` is a point where the runtime
583
583
can switch to another task running in the same component instance or start a
584
584
new task in response to an incoming export call.
585
585
@@ -598,20 +598,20 @@ the runtime to switch to another ready task, but without blocking on I/O (as
598
598
emulated in the Python code here by awaiting a ` sleep(0) ` ).
599
599
``` python
600
600
async def yield_ (self ):
601
- self .inst.active .release()
601
+ self .inst.fiber .release()
602
602
await asyncio.sleep(0 )
603
- await self .inst.active .acquire()
603
+ await self .inst.fiber .acquire()
604
604
```
605
605
606
606
Lastly, when a task exists, the runtime enforces the guard conditions mentioned
607
- above and releases the ` active ` lock, allowing other tasks to start or make
607
+ above and releases the ` fiber ` lock, allowing other tasks to start or make
608
608
progress.
609
609
``` python
610
610
def exit (self ):
611
611
assert (self .events.empty())
612
612
trap_if(self .borrow_count != 0 )
613
613
trap_if(self .num_async_subtasks != 0 )
614
- self .inst.active .release()
614
+ self .inst.fiber .release()
615
615
```
616
616
617
617
While ` canon_lift ` creates ` Task ` s, ` canon_lower ` creates ` Subtask ` objects:
@@ -2100,10 +2100,10 @@ the caller can know whether it can reclaim the parameter and result memory
2100
2100
buffers) and delivering subsequent progress events to the calling task via the
2101
2101
` AsyncSubtask ` ` start ` and ` return_ ` methods (defined above).
2102
2102
2103
- Note that the async case does * not* release or reacquire the ` active ` lock
2103
+ Note that the async case does * not* release or reacquire the ` fiber ` lock
2104
2104
since (due to the ` trap_if_on_stack ` reentrance guard in ` Task.enter ` ) the
2105
2105
` callee ` is necessarily in another component instance (which has a separate
2106
- ` active ` lock). This allows fine-grained inter-component task interleaving (up
2106
+ ` fiber ` lock). This allows fine-grained inter-component task interleaving (up
2107
2107
to and including preemptive multithreading) which doesn't break regular async
2108
2108
codes' assumptions due to the component shared-nothing model. This also means
2109
2109
that an async import calls are * not* allowed to switch to another task in the
@@ -2311,7 +2311,7 @@ async def canon_task_wait(task, ptr):
2311
2311
The ` trap_if ` ensures that, when a component uses a ` callback ` all events flow
2312
2312
through the event loop at the base of the stack.
2313
2313
2314
- Note that ` task.wait ` releases and reacquires the ` active ` lock and thus
2314
+ Note that ` task.wait ` releases and reacquires the ` fiber ` lock and thus
2315
2315
` canon_task_wait ` allows the runtime to switch to another active task in the
2316
2316
current component instance. Note also that ` task.wait ` can be called from a
2317
2317
sync-lifted ` SyncTask ` so that even fully synchronous code can make concurrent
@@ -2457,6 +2457,7 @@ def canon_thread_hw_concurrency():
2457
2457
[ Unicode Code Point ] : https://unicode.org/glossary/#code_point
2458
2458
[ Surrogate ] : https://unicode.org/faq/utf_bom.html#utf16-2
2459
2459
[ Name Mangling ] : https://en.wikipedia.org/wiki/Name_mangling
2460
+ [ Fibers ] : https://en.wikipedia.org/wiki/Fiber_(computer_science)
2460
2461
[ Asyncify ] : https://emscripten.org/docs/porting/asyncify.html
2461
2462
2462
2463
[ `import_name` ] : https://clang.llvm.org/docs/AttributeReference.html#import-name
0 commit comments