Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow blocking channels in wasm #77

Open
elias098 opened this issue Dec 3, 2023 · 5 comments
Open

Allow blocking channels in wasm #77

elias098 opened this issue Dec 3, 2023 · 5 comments

Comments

@elias098
Copy link

elias098 commented Dec 3, 2023

The blocking methods on channels got restricted to non wasm and while its a bad idea to use it on the main thread, it can be quite useful when you want to run blocking code on a web worker.

my current use is with https://crates.io/crates/wasm_thread

@notgull
Copy link
Member

notgull commented Dec 3, 2023

My impression is that blocking in a web worker is undefined and will immediately lead to a panic. So it doesn't make much sense to have blocking channels if it would immediately kill the thread, unless you have some other synchronization mechanism. But if you have that other synchronization mechanism, why use channels in the first place?

@daxpedda I know there was discussion of using these channels in winit, would it make sense to enable blocking on the web, even if it panics? I'm not familiar enough with web platforms to make the call

@elias098
Copy link
Author

elias098 commented Dec 4, 2023

in my experience it hasnt panicked yet, and web workers are allowed to run blocking code, it even got synchronous file readers.

the reason i need it to be blocking is because a library uses the read trait which afaik must be blocking.

im not sure if it changes anything with it but i do have atomics enabled to allow workers to share the same memory as the main thread.

@daxpedda
Copy link

daxpedda commented Dec 4, 2023

Blocking in Web workers is fine, it's just not allowed in the main thread (the Window context).

If blocking in the main thread is considered UB is a complicated question. Firstly, it's not defined in the Wasm spec yet what should happen if blocking is not allowed (see WebAssembly/threads#174), so right now it is actually some kind of UB in the literal sense.

But even if it were well defined, e.g. a trap is triggered when blocking is not allowed, it might still be UB from Rusts perspective. I will assume that Rust makes some assumptions on blocking that there won't simply be reentrancy in the same thread, so that sounds pretty UB to me unless Rust can detect that blocking failed, which it currently definitely can't. But I don't know the details on what kind of assumptions Rust makes and what it does with these assumptions.

In any case, without digging more into this and finding a general solution, the easiest way for async-channel is probably to detect if you are in the main thread (the Window context) and panic there instead.
But I believe the general request of allowing blocking for use in Web workers is valid. I don't think we need it in Winit though, it's still a question if we will use async-channel at all there.

im not sure if it changes anything with it but i do have atomics enabled to allow workers to share the same memory as the main thread.

I'm not aware of any Wasm instruction that allows you to block without the atomics proposal. I assume any other implementation out there just uses a loop or does it through the Atomics JS API. Rust std just panics when blocking isn't available (locks API selection -> non-atomic locks API implementation), but has no detection for the main thread, because Rust has to support pure Wasm and not just the browser.

@daxpedda
Copy link

daxpedda commented Dec 4, 2023

In any case, without digging more into this and finding a general solution, the easiest way for async-channel is probably to detect if you are in the main thread (the Window context) and panic there instead.

On another thought, this will only work in browsers. If async-channel wants to offer general Wasm support, you will have to guard the check behind a crate feature.

Additionally, for non-browser support, it can be guarded behind target_feature = "atomics" and for browser support as well unless you want to go through JS Atomics.

@notgull
Copy link
Member

notgull commented Dec 6, 2023

I can see this being used as a solution. However, it would require implementing support for it first in parking and then in event-listener. See smol-rs/parking#20 for that issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants