Skip to content

Add emscripten_promising_count() for querying in-flight async invocations#27377

Open
guybedford wants to merge 1 commit into
emscripten-core:mainfrom
guybedford:suspend-count
Open

Add emscripten_promising_count() for querying in-flight async invocations#27377
guybedford wants to merge 1 commit into
emscripten-core:mainfrom
guybedford:suspend-count

Conversation

@guybedford

Copy link
Copy Markdown
Collaborator

This adds a new emscripten_promising_count() function returning the number of async (promising) wasm invocations currently in flight, entered but with their returned promise not yet settled, under both ASYNCIFY and JSPI.

This allows runtime code to detect whether any async wasm invocations are pending, for example to verify or assert reentrancy invariants.

  • For JSPI (ASYNCIFY==2), the counter is bumped in Asyncify.makeAsyncFunction around each promising invocation, decrementing when the returned promise settles. All WebAssembly.promising usage (exports, dynCall, embind, makeDynCall codegen) is now routed through makeAsyncFunction as a single chokepoint, so this is a single bump per invocation rather than per import call.
  • For ASYNCIFY, the single suspendable invocation is counted from its first unwind until its final rewind completes, so the value is 0 or 1 (fiber swaps are not counted).
  • Without async support the function compiles to a constant 0.

One documented asymmetry: under JSPI a promising export counts for its entire invocation, while under ASYNCIFY an invocation is only counted once it first suspends.

Includes a new test_promising_count core test run under both ASYNCIFY and JSPI, observing the count from JS during an emscripten_sleep suspension, from C after resume, and confirming it returns to 0 after the invocation settles. Docs and ChangeLog updated.

Made with AI assistance under my review

…ions

Returns the number of async (promising) wasm invocations currently in
flight, under both ASYNCIFY and JSPI. For JSPI the counter is bumped in
Asyncify.makeAsyncFunction around each promising call, with all
WebAssembly.promising usage now routed through it; for ASYNCIFY it
tracks the single suspendable invocation from its first unwind until
its final rewind completes.

@sbc100 sbc100 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the current state is the we only support a single suspended stack at once, either with ASYNCIFY or JSPI? At least I think it should be.

If I'm wrong and we don't currently enforce this for JSPI, then perhaps we should land the internals of this counter, along with an assertion if its ever exceeds 1?

We can then add a the public function, once we add the ASYNCIFY_RENTRANT option (until we add that we should not allow more than one suspended stack I think).

If/when we do add a public function here, perhaps it should be called something like emscripten_suspended_stack_count? Or emscripten_asyncify_active_stacks? Just shedding here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants