This segment of code has assumptions that are incorrect for projects making use of multithreaded Wasm:
|
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.
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
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):
Alternatively the fix could go into the
async-lockproject.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.