Skip to content

fix(io): flush stdout before JS file reads - #1895

Closed
toprameen wants to merge 2 commits into
bendlang:mainfrom
toprameen:flush-js-file-read-prompts
Closed

toprameen wants to merge 2 commits into
bendlang:mainfrom
toprameen:flush-js-file-read-prompts

Conversation

@toprameen

Copy link
Copy Markdown
Contributor

When stdout is piped, a prompt written with IO.write can stay buffered while File.read_line waits for input. The shared JS file-read helper now flushes stdout before reading, so a client waiting for the prompt can respond.

The new regression checks stdout/read ordering. It fails on the previous code and passes across the tested runtimes. Focused file-read/output-order tests, Linux container checks and the repository gate (54/54) pass.

@toprameen
toprameen marked this pull request as ready for review October 27, 2026 18:22
@Lorenzobattistela

Copy link
Copy Markdown
Collaborator

Thanks for finding and fixing this! Closing in favour of #1899, which fixes it in the event loop instead of in File.read alone: the JS File and Process effects now park, so io_wait writes held stdout before any of them blocks, as C does. That also covers File.open, File.write and Process.run, which had the same deadlock. Your file_read_prompt test passes on #1899 (and fails on main), so the case you hit is covered.

nicolas-abril added a commit that referenced this pull request Oct 27, 2026
From #1895: IO.write("prompt> ") with no newline, then File.read_line.
The JS twin checks that the prompt was written before the read ran.
Passes with this PR; on main the read runs first.

Co-authored-by: toprameen <11931132+toprameen@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>
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