fix panic when dropping waitable set with stackful waiter#12971
Conversation
| @@ -0,0 +1,135 @@ | |||
| ;;! component_model_async = true | |||
| ;;! component_model_async_stackful = true | |||
There was a problem hiding this comment.
Can this be rewritten to not use *_stackful = true?
I think that should be fairly easy, just using a callback option that only has an unreachable instruction
There was a problem hiding this comment.
I don't believe that's possible (or at least, I can't think of a way). The problem is that the test relies on being able to re-enter the instance while another task is already running on that instance, but that's not allowed if the already-running task is stackless (i.e. callback-based).
I just verified that by adding callbacks to component $C's two exports and got a "deadlock detected: event loop cannot make further progress" trap instead of the desired "cannot drop waitable set with waiters" trap.
There was a problem hiding this comment.
For the record, I imagine we could do this by enabling component_model_threading instead component_model_stackful and spawning a thread in the task, but I don't think that's any better or more understandable than what we have now.
tests/misc_testsuite/component-model/async/drop-waitable-set-stackful.wast
Outdated
Show resolved
Hide resolved
In `waitable_set_drop`, we must check for any waiters on the set and, if there are any present, trap without removing the set. Otherwise, if one or more of those waiters are stackful (i.e. `WaitMode::Fiber(_)`), then removing the set will cause `StoreFiber::drop` to be called, which will panic since the fiber is still running. By trapping without removing the set, we defer dropping the fiber(s) until the `Store` is disposed, at which point we will dispose of them gracefully prior to dropping them.
6ff9712 to
51ea1af
Compare
In
waitable_set_drop, we must check for any waiters on the set and, if there are any present, trap without removing the set. Otherwise, if one or more of those waiters are stackful (i.e.WaitMode::Fiber(_)), then removing the set will causeStoreFiber::dropto be called, which will panic since the fiber is still running.By trapping without removing the set, we defer dropping the fiber(s) until the
Storeis disposed, at which point we will dispose of them gracefully prior to dropping them.