Skip to main content

TaskGroupHook

Trait TaskGroupHook 

Source
pub trait TaskGroupHook:
    Send
    + Sync
    + 'static {
    // Required methods
    fn handle_start(&mut self, id: TaskGroupId) -> Result<(), Error>;
    fn handle_enter(&mut self, id: TaskGroupId) -> Result<(), Error>;
    fn handle_exit(&mut self, id: TaskGroupId) -> Result<(), Error>;
    fn handle_finish(&mut self, id: TaskGroupId) -> Result<(), Error>;
}
Expand description

Trait for being notified by the runtime of activity concerning a “task group”.

The Component Model specification has no notion of a “task group”1, but we define one here in order to enable embedders to associate guest->host calls with corresponding host->guest calls in a predictable way.

A TaskGroupId is allocated whenever a guest task is created for a host->guest call, and handle_start is called. That task is considered the “root” task for the task group, and any subtasks transitively created by it will also be considered part of that task group. Whenever the runtime switches (Component-Model-level) threads, it will call handle_exit for the group to which the old thread belonged, if any, and call handle_enter for the group to which the new thread belongs. Only once all the threads of all those tasks have exited (and the guest has dropped any subtask handles referring to any of those tasks) will the TaskGroupId be deallocated, at which point handle_finish will be called.

Note that a given TaskGroupId may be reused after handle_finish is called, so implementations of this trait must take care to reset any state associated with it.

Each of these functions may return an error, in which case any running guest code will trap, the store will be poisoned such that it cannot be used to run any further guest code, and the error will propagate back to the host->guest caller. Furthermore, if and when the store is poisoned due to any unrecoverable error (whether it was produced by the hook, the guest, or the host), the currently-entered group will be exited (i.e. handle_exit called), if any, and any started group will be finished (i.e. handle_finish called).

As of this writing, https://github.com/WebAssembly/component-model/pull/730 (which adds thread.set-task and related intrinsics) has not yet been merged. Once it has, and Wasmtime adds support for that feature, it will be possible for guest threads to change their task; in that case, the thread will effectively join whatever group the new task belongs to, which might not be the same as that of the old task. In addition, the new thread.get-task intrinsic will give the guest another way (besides subtask handles) to keep tasks alive beyond the point when all their threads have exited or switched tasks, in which case the group it belongs to will not be disposed until all such tasks have been dropped using task.drop.


  1. Although it does imply such a notion in the discussion of “semantic tail calls”. ↩

Required Methods§

Source

fn handle_start(&mut self, id: TaskGroupId) -> Result<(), Error>

Handle notification that a new task group has been created (i.e. a host->guest call has been prepared).

Source

fn handle_enter(&mut self, id: TaskGroupId) -> Result<(), Error>

Handle notification that the runtime has switched to a thread belonging to the specified task group.

Source

fn handle_exit(&mut self, id: TaskGroupId) -> Result<(), Error>

Handle notification that the runtime has switched away from a thread belonging to the specified task group.

Source

fn handle_finish(&mut self, id: TaskGroupId) -> Result<(), Error>

Handle notification that the specified task group has been disposed of (i.e. the task created for the host->guest call for which the task group was created has exited, along with any and all subtasks transitively created by that task, and the guest has dropped any and all handles to those tasks).

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§