Repository navigation
fix(io): write held stdout before a JS File read - #1893
Closed
MattCozendey wants to merge 1 commit into
Closed
MattCozendey wants to merge 1 commit into
MattCozendey wants to merge 1 commit into
Conversation
On JS, IO.print holds stdout off a terminal, and File.read* blocked in readvSync with the text still held, so a program that prints and then waits for a reply deadlocked. C already writes it before it waits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
|
Closing in favour of #1899, which fixes this in the loop instead of in File.read alone. The JS File and Process effects now park themselves, so io_wait flushes held stdout before any of them blocks, as C does through io_work. This also covers File.open and Process.run, which had the same deadlock. Your test file_read_stdout_order is kept in #1899. Thanks for finding this! |
nicolas-abril
added a commit
that referenced
this pull request
Oct 27, 2026
On JS, File.open/read*/size/write* and Process.run ran synchronously inside the effect, so the loop never reached io_wait and never wrote what IO.print holds before blocking: a program that prints and then reads from a peer waiting for that output deadlocked. C runs these through io_work, parks the fiber, and flushes in io_wait. Each of these effects now parks itself with io_park_on, due at once, so it runs at the next io_wait, after its io_sync, as in C. Other fibers run before its result, as in C. io_wait skips select when it waits on no fd with a zero timeout, so parked files need no bun:ffi on node. File.write's own io_sync goes away. Supersedes #1893; its test file_read_stdout_order is kept. Co-authored-by: MattCozendey <MattCozendey@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nicolas-abril
added a commit
that referenced
this pull request
Oct 27, 2026
…ut (#1899) On JS, the File effects and Process.run ran synchronously inside the effect, so the loop never reached io_wait and never wrote what IO.print holds before blocking: a program that prints and then reads from a peer waiting for that output deadlocked. C runs these through io_work, parks the fiber, and flushes in io_wait. Each of these effects (File.open/open_bytes, read/read_line/read_bytes/read_at, size, write/write_bytes/write_at, Process.run) now parks itself with io_park_on, due at once, so it runs at the next io_wait, after its io_sync, as in C. io_wait skips select when it waits on no fd with a zero timeout, so parked files need no bun:ffi on node. File.write's own io_sync goes away. Tests: file_read_stdout_order (from #1893), file_read_prompt (from #1895), and file_open_fifo_peer, a FIFO whose writer waits for held stdout, which hangs the JS lane on main. Co-authored-by: MattCozendey <75740566+MattCozendey@users.noreply.github.com> Co-authored-by: toprameen <11931132+toprameen@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Bug: on JS,
IO.printholds stdout when it is a pipe.File.read*blocks inreadvSyncwithout writing it out first, so a program that prints and then waits for a reply deadlocks. C writes it out before it waits (io_syncbeforeselect).Repro:
{ printf 'a\n'; sleep 3; printf 'b\n'; } | node prog.js, whereprog.jsechoes eachFile.read_lineof/dev/stdin. JS printsaafter 3 s; native prints it at once.Fix:
io_sync()at the top offile_read_with, asfile_write.jsdoes. Onlybend2/effs/file_read.js(+2 lines) and one test intests/io/change.Cost: a loop that prints between reads now writes on each read, as C does.
Tested: new
tests/io/file_read_stdout_order: onmain, the interpreter, Bun and Node printtwo one three, and native passes; with the fix, all four pass. Nearbytests/iofile and stdout tests pass. Linux (WSL2), Bun + Node. Not tested: macOS, the cluster gates.🤖 Generated with Claude Code