Open temeddix opened 1 year ago
Threads are not yet supported. I do want to support them, but I don't think it will be a trivial change. webworkers don't allow sharing javascript objects, so directly sharing the Fd
list between all threads is not possible. Instead some way of keeping them on a single thread and then doing message passing whenever another thread wants to call a method on it will be necessary. The standard message passing way for webworkers is asynchronous and webassembly is fully synchronous, so using that method won't be possible afaik. Instead I think it will be necessary to manually implement a message queue on top of SharedArrayBuffer
which can block threads using Atomics.wait
/Atomics.notify
. See also https://github.com/bjorn3/browser_wasi_shim/issues/14.
Yeah, I am aware that message passing is crucial between web workers to send messages in JS. However in native languages like Rust, you can simply share native channels inside WebAssembly.Memory
and communicate using them. IMO, All we have to do is to ensure that all the new web workers share the same WebAssembly.Memory
and provide some spawn mechanism for native functions with SharedArrayBuffer
.
I think we should guide the users about only two things:
WebAssembly.Memory
that this shim library will use, when instantiating wasm with this shim(Perhaps this can be automatically done).I have experience with web workers and SharedArrayBuffer
from Rinf and async_wasm_task (I'm the maintainer). I'm also very familiar with typescript. May I work on this idea and create a PR, if acceptable?
Provide the WebAssembly.Memory that this shim library will use, when instantiating wasm with this shim(Perhaps this can be automatically done).
There are two shared memories that are necessary. One shared between the wasm instances for each thread and one for the message passing. browser_wasi_shim can't use the shared memory used by wasm for message passing as that would likely cause corruption for the wasm module if it thinks it can write to memory while at the same time browser_wasi_shim is using it for the message passing.
I think it would be possible to have a method on WASI
(Or maybe we should have a separate SharedWASI
) which returns an Object
containing all necessary SharedArrayBuffer
and Webassembly.Memory
instances which can be passed to postMessage
and on the other side can be turned back into a WASI
(or SharedWASI
) instance. Or alternatively we could have browser_wasi_shim ship with a webworker which is used for all thread spawning attempts and handles all this passing behind the scenes. This would be less flexible though.
May I work on this idea and create a PR, if acceptable?
Absolutely!
Having trouble with synchronization? Although old-school, partytown uses an interesting trick to achieve synchronization. Of course, you can also use Atomics.
https://dev.to/adamdbradley/how-partytown-s-sync-communication-works-4244
Blocking http requests to a service worker is an interesting hack. I'm afraid it will deadlock if a service worker gets a channel message (for sending non-serializable things like the shared memory to write to) and http requests to service in the wrong order. And it also doesn't really help with the debugging side of things. Any multithreading makes debugging so much harder with current browser debugger implementations. I tried implementing thread support a while back, but hit several debugger crashes, broken single stepping behavior, breakpoints not working and other bugs.
Hi, thanks for this wonderful effort :)
I'm very interested in running thread code from WASI
.wasm
file on the browser. Is it possible right now? If not, can I make a PR for that using web workers?