You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
don't trap on idle in Instance::run_concurrent (#11756)
Previously, `Instance::run_concurrent` returned `Trap::AsyncDeadlock` when all
guest tasks and background host tasks had completed, and yet the future
parameter it was passed still hadn't resolved. The theory was that this
indicated a mistake on the host embedder's part, but it turns out there are
scenarios where this is actually what the embedder wanted.
For example, consider a host embedder that implements a pool of worker tasks,
each of which runs a loop inside async closure passed to
`Instance::run_concurrent`. In this case, each worker accepts jobs (which
involve calling guest functions) from a multiple-producer, multiple-consumer job
queue, adding them to a `futures::stream::FuturesUnordered` so they can be run
concurrently. When all the jobs accepted by a given worker have finished, there
may be a lull during which no new jobs are yet available. In that case, the
worker _could_ break out of the loop, resolve the future, allow
`Instance::run_concurrent` to finish, and wait until the next job arrives before
calling `Instance::run_concurrent` again, but that's more awkward (i.e. nested
loops, complicated control flow) than just a single loop inside
`Instance::run_concurrent` that goes idle now and then.
In short, the closure passed to `Instance::run_concurrent` might experience
delays between when a set of guest tasks have completed and when the next set
are ready to start, and that's not necessarily a bug.
Internally, I've added a new `run_concurrent_trap_on_idle` function, which
provides the original, trapping behavior, and I'm using it to implement
`[Typed]Func::call_async`, in which case it _is_ an error if the event loop goes
idle without the future resolving. If this turns out to be useful as part of
the public API, we can change the `pub(super)` to `pub`.
Signed-off-by: Joel Dice <[email protected]>
0 commit comments