Skip to content

update subtask.cancel implementation to match latest spec tweak - #14382

Merged
dicej merged 1 commit into
bytecodealliance:mainfrom
dicej:subtask-cancel-tweaks
Sep 23, 2026
Merged

dicej merged 1 commit into
bytecodealliance:mainfrom
dicej:subtask-cancel-tweaks

Conversation

@dicej

@dicej dicej commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

WebAssembly/component-model#726 refined the behavior of subtask.cancel to more closely match how async-lowered calls behave, meaning the runtime must resume the cancelling thread specifically as soon as the cancellee suspends or exits.

This required some refactoring, and I believe it's a net simplification of how the runtime decides which thread to switch to and when.

  • Both guest->guest calls and subtask.cancel use a new SuspendReason::YieldingToSubtask variant which replaces WaitingForGuestSubtask and means "I'm yielding specifically to the specified (via ConcurrentState::switch_item) subtask and expect to be resumed when that subtask suspends or exits."

  • I've removed GuestTask::switch_item in favor of a new ConcurrentState::next_switch_item field. This addresses a case exercised by the new cancel-resumed-callback-switch.wast test where a subtask, while being cancelled, explicitly resumes a thread belonging to a different task, which then suspends, in which case we need to resume the cancelling thread. This new next_switch_item field is saved and restored as needed so that a stack of cancels and guest->guest calls can each yield to their respective subtasks and return to their respective callers/cancellers without clobbering each other.

  • The new cancel-targeted-resume.wast test revealed that Wasmtime was out of compliance regarding CALLBACK_CODE_YIELD; when a task is cancelled while it is stacklessly yielding, we must promote it so the cancel event can be delivered deterministically. I've addressed this by defining a new WakeOnCancel enum type which can represent a thread which is waiting cancellably, yielding cancellably, or neither.

Since the aforementioned spec PR has not yet been merged as of this writing, I haven't updated the tests/component-model submodule yet, but I've verified locally that the new tests pass.

WebAssembly/component-model#726 refined the behavior of
`subtask.cancel` to more closely match how async-lowered calls behave, meaning
the runtime must resume the cancelling thread specifically as soon as the
cancellee suspends or exits.

This required some refactoring, and I believe it's a net simplification of how
the runtime decides which thread to switch to and when.

- Both guest->guest calls and `subtask.cancel` use a new
  `SuspendReason::YieldingToSubtask` variant which replaces
  `WaitingForGuestSubtask` and means "I'm yielding specifically to the specified
  (via `ConcurrentState::switch_item`) subtask and expect to be resumed when
  that subtask suspends or exits."

- I've removed `GuestTask::switch_item` in favor of a new
  `ConcurrentState::next_switch_item` field.  This addresses a case exercised by
  the new `cancel-resumed-callback-switch.wast` test where a subtask, while
  being cancelled, explicitly resumes a thread belonging to a different task,
  which then suspends, in which case we need to resume the cancelling thread.
  This new `next_switch_item` field is saved and restored as needed so that a
  stack of cancels and guest->guest calls can each yield to their respective
  subtasks and return to their respective callers/cancellers without clobbering
  each other.

- The new `cancel-targeted-resume.wast` test revealed that Wasmtime was out of
  compliance regarding `CALLBACK_CODE_YIELD`; when a task is cancelled while it
  is stacklessly yielding, we must promote it so the `cancel` event can be
  delivered deterministically.  I've addressed this by defining a new
  `WakeOnCancel` enum type which can represent a thread which is waiting
  cancellably, yielding cancellably, or neither.

Since the aforementioned spec PR has not yet been merged as of this writing, I
haven't updated the `tests/component-model` submodule yet, but I've verified
locally that the new tests pass.
@dicej
dicej requested a review from alexcrichton September 22, 2026 22:54
@dicej
dicej requested a review from a team as a code owner September 22, 2026 22:54
@github-actions github-actions Bot added the wasmtime:api Related to the API of the `wasmtime` crate itself label Sep 23, 2026
@dicej
dicej added this pull request to the merge queue Sep 23, 2026
Merged via the queue into bytecodealliance:main with commit 437161a Sep 23, 2026
54 checks passed
@dicej
dicej deleted the subtask-cancel-tweaks branch September 23, 2026 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wasmtime:api Related to the API of the `wasmtime` crate itself

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants