Add wasm32-unknown-emscripten target support#1969
Draft
guybedford wants to merge 1 commit into
Draft
Conversation
Author
|
Yeah that could work - let me see if I can come up with a way for the
callback mechanism to only be on the Tokio side instead.
…On Sun, Jul 12, 2026 at 14:34 Alice Ryhl ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/poll.rs
<#1969 (comment)>:
> @@ -444,6 +444,40 @@ impl Poll {
}
}
+#[cfg(all(target_os = "emscripten", feature = "os-poll"))]
+impl Poll {
+ /// Create a `Poll` whose epoll set carries a persistent, non-blocking
+ /// readiness callback for the lifetime of the `Poll`. Instead of blocking in
+ /// [`Poll::poll`], the emscripten runtime delivers up to `capacity` ready
+ /// events to `callback` on a fresh host tick whenever the set makes progress
+ /// (needs no JSPI/ASYNCIFY). The callback is unregistered when the `Poll` is
+ /// dropped.
+ ///
+ /// The `callback` may freely re-enter this `Poll`/`Registry` (e.g. register
+ /// or deregister sources): it holds no internal borrow while running.
+ pub fn new_with_callback<F>(capacity: usize, callback: F) -> io::Result<Poll>
The code already copies the events into the Events buffer, so instead of
passing them to a callback, I don't see why you can't just keep them around
in said buffer until the next call to poll and return them to the caller
then. That wouldn't need any user-facing API change.
—
Reply to this email directly, view it on GitHub
<#1969?email_source=notifications&email_token=AAESFSWFKSGVAOT73HVO2FT5EP75RA5CNFSNUABKM5UWIORPF5TWS5BNNB2WEL2QOVWGYUTFOF2WK43UKJSXM2LFO4XTINRYGA4DEMJSGI4KM4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KYZTPN52GK4S7MNWGSY3L#discussion_r3567166992>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAESFSVF7QLBRUCJ7LS35NL5EP75RAVCNFSNUABEKJSXA33TNF2G64TZHMZDGMJTHA4TQNB3JFZXG5LFHM2DQNRQGAZDGMJUHGQXMAQ>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Member
|
Why do you want the callback mechanism on the Tokio side rather than just storing them in this buffer until the next time Tokio calls |
e7f7165 to
e3ecd61
Compare
Adds `wasm32-unknown-emscripten` as a target for mio, plus a CI job that runs the suite under Node. Resolves tokio-rs#642. Emscripten exposes a real epoll backed by its runtime event loop, so the existing Linux epoll selector is reused rather than adding a new backend. The wasm `compile_error!` guard is relaxed to let emscripten through, and the `epoll`/`eventfd`/pipe-waker cfg lists gain emscripten. Because emscripten cannot block in `epoll_wait` without JSPI/ASYNCIFY, the epoll fd is exposed via `AsRawFd` on `Poll`/`Registry` so the runtime driving mio can arm emscripten's `emscripten_epoll_set_callback` on it directly, signalling on a fresh host tick whenever the set has ready events. A zero-timeout `Poll::poll` remains available as a synchronous readiness probe where a blocking wait is impossible. AF_UNIX support is stream-only: emscripten's node-backed sockets have no datagram primitive, so `UnixDatagram` and the `socketpair`-based helpers are not compiled there. Sockets set `O_NONBLOCK` via `fcntl` since emscripten's `socket(2)` silently strips `SOCK_NONBLOCK`/`SOCK_CLOEXEC`. The suite spawns OS threads (socket-peer test harnesses), so std is rebuilt with atomics via -Zbuild-std and linked -pthread with -sPROXY_TO_PTHREAD. Blocking harness socket ops (accept/recv) block their pthread through emscripten's sync-proxy wait primitive (`_emscripten_fd_wait`) - no JSPI or stack suspension is involved anywhere in the suite. NODERAWFS/NODERAWSOCKETS back the filesystem and sockets with node's. This needs nightly + rust-src. No custom target spec is required: nightly now emits the __main_argc_argv entry point (rust-lang/rust#158937). Doctests are skipped on this target: rustdoc does not apply the emcc link args, so the examples cannot be linked with the socket/thread runtime. Temporary, until the dependencies land upstream: * Cargo.toml patches libc to guybedford/libc#emscripten for the emscripten epoll/pthread externs (rust-lang/libc#5270). * the CI job builds against the guybedford/emscripten `cf` fork, which carries the epoll callback, `_emscripten_fd_wait` blocking-ops, AF_UNIX pathname stream socket, and multicast getsockopt patches this target depends on. The two `reconnect_udp_socket_*` tests are ignored on emscripten: libuv does not re-associate a connected UDP socket when it is reconnected to a new peer, so no readiness is delivered for the new peer. Suite result: 144 passed, 0 failed, 5 ignored under Node - green on CI.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft PR for #642.
Adds
wasm32-unknown-emscriptenas a target for mio, with a CI job running the suite under Node. Opening as a draft for now since it depends on unreleased patchsets for Emscripten and Rust's libc.This lays the groundwork for Tokio support for Emscripten. Initially I did not plan to PR Mio, but in discussion with @Darksonn and @Noah-Kennedy it was suggested to use Mio if possible, and this has worked out well in my opinion.
Once emscripten-core/emscripten#27207 lands, Emscripten exposes a real epoll, so the existing Linux epoll selector can reused rather than adding a new backend.
Patch Sets
This PR will remain a draft while it relies on the following upstream patches:
In addition Rust nightly is needed for two additional patches only landed recently.
Test status
Tests run directly on the Emscripten Node.js build with
NODERAWSOCKETSandNODERAWFSto provide a transparent runner without further harness configuration being necessary.Tests use JSPI to be able to support the harness integration, but can work without JSPI when integrating with the callback model - a dedicated
emscriptentest is included for these.tcp_stream::raw_fd(pending net: support sync connect for BoundSocket nodejs/node#64375), plus twoPOLLRDHUP/close-event cases shared with other targets, and two rebinding ephemeral port errors.Early feedback on the approach very much welcome.