Skip to content

Panic on multithreaded browser Wasm #89

@kettle11

Description

@kettle11

This segment of code has assumptions that are incorrect for projects making use of multithreaded Wasm:

async-executor/src/lib.rs

Lines 276 to 288 in 6c70369

fn state(&self) -> &Arc<State> {
#[cfg(not(target_family = "wasm"))]
{
return self.state.get_or_init_blocking(|| Arc::new(State::new()));
}
// Some projects use this on WASM for some reason. In this case get_or_init_blocking
// doesn't work. Just poll the future once and panic if there is contention.
#[cfg(target_family = "wasm")]
future::block_on(future::poll_once(
self.state.get_or_init(|| async { Arc::new(State::new()) }),
))
.expect("encountered contention on WASM")

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions