single_threaded_task_pool
scope
api doesn't work in wasm #1924
Description
Bevy version
0.5 and d119c1ce14da59089a65373d59715a41d05251ad
Operating system & version
Firefox & Chromium
What you did
Trying to use the task pool to execute several tasks, I hoped to have the same code running in both wasm and native
use bevy::{prelude::*, tasks::prelude::*};
fn main() {
let mut builder = App::build();
builder.add_plugins(DefaultPlugins);
let asset_io = bevy::asset::create_platform_default_asset_io(&mut builder);
builder
.insert_resource(asset_io)
.init_resource::<Vec<String>>()
.add_startup_system(get_from_future.system())
.add_system(log_stuff.system())
.run();
}
fn get_from_future(
task_pool: Res<ComputeTaskPool>,
mut expensive_to_get: ResMut<Vec<String>>,
asset_io: Res<Box<dyn bevy::asset::AssetIo>>,
) {
let asset_io = &*asset_io;
*expensive_to_get = task_pool
.scope(|scope| {
for i in 0..3 {
scope.spawn(async move {
std::str::from_utf8(
&asset_io
.load_path(&std::path::Path::new(&format!("file_{}.big", i)))
.await
.unwrap(),
)
.unwrap()
.to_string()
});
}
})
.into_iter()
.collect();
}
fn log_stuff(expensive_to_get: Res<Vec<String>>) {
bevy::log::warn!("got {:?}", *expensive_to_get);
}
This works on native!
Building this for wasm32 gives an error:
26 | scope.spawn(async move {
| ^^^^^ future created by async block is not `Send`
Indeed, spawn
requires the future to be Send
in the single_threaded_task_pool. This could probably be removed anyway as it calls spawn_local
which doesn't need Send
bevy/crates/bevy_tasks/src/single_threaded_task_pool.rs
Lines 129 to 131 in d119c1c
Let's try to run this with spawn_local
to check if it would work better.At least it compiles that way!
And crash in the browser
test.js:276 panicked at 'assertion failed: `(left == right)`
left: `true`,
right: `false`: cannot recursively acquire mutex',
And rightly so. In the scope
function:
bevy/crates/bevy_tasks/src/single_threaded_task_pool.rs
Lines 79 to 83 in d119c1c
The
lock()
is on a mutex, and that can't work because you can't block in wasm...
Using the task pool in wasm will work for trivial task that aren't long enough to lock the mutex, but will fail for any real case...
I tried a few things but couldn't get it to work