async-executor icon indicating copy to clipboard operation
async-executor copied to clipboard

Panic on multithreaded browser Wasm

Open kettle11 opened this issue 1 year ago • 4 comments

This segment of code has assumptions that are incorrect for projects making use of multithreaded Wasm: https://github.com/smol-rs/async-executor/blob/6c70369102f947a9f4abc48c370c5ab8e7810840/src/lib.rs#L276-L288

Multithreaded Wasm is possible with Rust, but the chief limitation is that the main thread panics if it tries to block/wait. However it is allowed to busy-loop as a form of waiting. Crates like wasm_sync reimplement synchronization primitives and use busy-looping instead of blocking on the main thread.

So here's the puzzle: projects like Bevy depend on async-executor, and right now I'm trying to make Bevy multithreaded. There needs to be a workaround to prevent outright crashing if contention is encountered on the main thread due to the above snippet of code.

It could be modified to work like this on Wasm (preferably only on the main thread):

loop {
    if let Ok(state) = self
        .state
        .get_or_try_init_blocking::<()>(|| Ok(Arc::new(State::new())))
    {
        return state;
    }
}

Alternatively the fix could go into the async-lock project.

Would this project be willing to take on a fix like that to unblock upstream users of multithreaded Wasm?

Perhaps eventually this workaround could land in the standard library itself, but there are challenges with that as well. In an even better world browsers would allow waiting on the main thread, but that will not be considered any time soon.

kettle11 avatar Jan 23 '24 23:01 kettle11