Skip to content

Refactor async poll()/select() onto a per-inode readiness wait-queue#27226

Merged
sbc100 merged 6 commits into
emscripten-core:mainfrom
guybedford:readiness-refactor
Jul 1, 2026
Merged

Refactor async poll()/select() onto a per-inode readiness wait-queue#27226
sbc100 merged 6 commits into
emscripten-core:mainfrom
guybedford:readiness-refactor

Conversation

@guybedford

@guybedford guybedford commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

This refactors out a partial base from #27207.

Move the readiness wait-queue onto FSNode (addListener/notifyListeners) so dup'd fds share one queue, and rewrite the suspending poll() path (readPollfds/writePollfds/pollWait) on top of it. Producers (SOCKFS, PIPEFS) now notify the node on readiness transitions, and close() wakes waiters with POLLNVAL.

  • FSNode gains addListener(cb, exclusive) / notifyListeners(flags) — a per-inode Set of listener entries. It lives on the node (not the fd) so dup'd fds share one queue. Only nodes with real readiness (sockets, pipes) ever populate it; always-ready types (regular files, ttys) never touch it.
  • The suspending poll() path is rewritten on top of it (readPollfds/writePollfds/pollWait/pollOne), replacing the old doPollAsync + makeNotifyCallback machinery.
  • Producers now notify the node on a readiness transition: PIPEFS on writes, SOCKFS via its emit bridge, and close() wakes any waiter with POLLNVAL.
  • Socket hangup semantics tightened: a peer half-close is POLLRDHUP (only a fully closed connection is POLLHUP), and a queued client makes a listening socket POLLIN.

The stream_ops.poll backend handler signature changes from poll(stream, timeout) to poll(stream) returning the current readiness mask.

Note: the exclusive parameter on addListener and the round-robin wakeup path in notifyListeners are deliberately layered in here as groundwork for the EPOLLEXCLUSIVE handling that lands in the epoll followup (#27207). No caller passes exclusive in this PR yet, so that branch is currently inert — it's included now to keep the wait-queue API stable across the split.

Move the readiness wait-queue onto FSNode (addListener/notifyListeners) so
dup'd fds share one queue, and rewrite the suspending poll() path
(readPollfds/writePollfds/pollWait) on top of it. Producers (SOCKFS, PIPEFS)
now notify the node on readiness transitions, and close() wakes waiters with
POLLNVAL.

The stream_ops.poll backend handler signature changes from
poll(stream, timeout) to poll(stream) returning the current readiness mask.
@guybedford guybedford force-pushed the readiness-refactor branch from f5b9a75 to 38d299d Compare July 1, 2026 00:26

@sbc100 sbc100 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! Thanks for splitting this out.

lgtm with some comments

Comment thread src/lib/libsyscall.js Outdated
Comment thread src/lib/libsyscall.js Outdated
Comment thread src/lib/libsyscall.js
Comment thread src/lib/libsyscall.js
Comment thread src/lib/libsyscall.js
Comment thread src/lib/libsyscall.js Outdated
Comment thread src/lib/libsyscall.js Outdated
@guybedford guybedford force-pushed the readiness-refactor branch from 54603a4 to 6d38401 Compare July 1, 2026 01:44
Comment thread src/lib/libsyscall.js Outdated
Comment thread src/lib/libsyscall.js Outdated

@sbc100 sbc100 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

Comment thread ChangeLog.md Outdated
Comment thread test/codesize/test_codesize_file_preload.expected.js
Comment thread test/codesize/test_codesize_file_preload.expected.js
@sbc100 sbc100 merged commit 85d0a51 into emscripten-core:main Jul 1, 2026
39 checks passed
Comment thread src/lib/libsyscall.js
@guybedford guybedford deleted the readiness-refactor branch July 1, 2026 16:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants