chemicstry / wasm_thread

A rust `std::thread` replacement for wasm32 target
Apache License 2.0
123 stars 16 forks source link

Error when calling `join()` #11

Closed the-drunk-coder closed 2 years ago

the-drunk-coder commented 2 years ago

Hi, I tried to build a little scheduler using wasm_thread, based on the simple example (build with the provided build.sh script)

When I call join() on the JoinHandle, I get the following error in the console:

Uncaught RuntimeError: Atomics.wait cannot be called in this context
    at std::thread::park::h593d412d90d62fe8 (simple_bg.wasm:0xa15d)
    at std::thread::local::LocalKey<T>::with::h7c7778a2607becf9 (simple_bg.wasm:0xb690)
    at futures_executor::local_pool::block_on::hf38892d64f63bc2a (simple_bg.wasm:0xc0e9)
    at wasm_thread::JoinHandle<T>::join::hb8eb16f7d78b7dfe (simple_bg.wasm:0xc237)
    at stop_scheduler (simple_bg.wasm:0x7531)
    at WebAudioSwitch.<anonymous> (simple.html:21:10)
    at WebAudioSwitch.sendEvent (webaudio-controls.js:159:12)
    at WebAudioSwitch.pointerdown (webaudio-controls.js:1046:14)
$std::thread::park::h593d412d90d62fe8 @ simple_bg.wasm:0xa15d
$std::thread::local::LocalKey<T>::with::h7c7778a2607becf9 @ simple_bg.wasm:0xb690
$futures_executor::local_pool::block_on::hf38892d64f63bc2a @ simple_bg.wasm:0xc0e9
$wasm_thread::JoinHandle<T>::join::hb8eb16f7d78b7dfe @ simple_bg.wasm:0xc237
$stop_scheduler @ simple_bg.wasm:0x7531
(anonymous) @ simple.html:21
sendEvent @ webaudio-controls.js:159
pointerdown @ webaudio-controls.js:1046

Best, N

chemicstry commented 2 years ago

You get such errors when trying to do any blocking operation that uses atomics on the main thread (README). I'm not sure if join() was working before, but if it did then it seems that futures::executor::block_on got smarter and it attempts to park the thread instead of busy polling, or thread::park() was implemented for wasm in newer rust versions.

In any case, if you want to block on the main thread, you should make your scheduler entry point async fn and use join_async().await. It is possible to hack around and manually poll future returned by join_async(), but browsers really don't like busy waiting and things like DOM, network, worker spawning, etc. usually freeze until non-async function terminates.

Alternatively, you could start your scheduler in a web worker, which does allow atomic wait and join() would work fine there. This limitation only applies to the main browser thread.

the-drunk-coder commented 2 years ago

Ah right, yes ... sorry, must have missed that. Thanks for the quick reply !