mirror of
https://github.com/oven-sh/bun
synced 2026-02-11 11:29:02 +00:00
## Summary
Fixed a race condition where calling `pause()` followed by `resume()` on
`process.stdin` would prevent data from being received, causing the
process to exit immediately instead of listening for input.
## Root Cause
The issue was in the pause/resume event handling logic in
`ProcessObjectInternals.ts`:
1. When `pause()` is called, the "pause" event handler schedules a
`disown()` call for the next tick
2. When `resume()` is called immediately after, it calls `own()` to
acquire a stream reader
3. On the next tick, the scheduled `disown()` from step 1 executes and
incorrectly releases the reader that was just acquired in step 2
This race condition left the stream without a reader, so no data could
be received.
## Solution
Added a `pendingDisown` flag that:
- Gets set to `true` when scheduling a disown operation
- Gets cleared to `false` when `own()` is called (during resume)
- Prevents the scheduled disown from executing if it has been cancelled
by a subsequent `own()` call
## Test Plan
- [x] Added regression tests in
`test/regression/issue/stdin-pause-resume.test.ts`
- [x] Verified fix with original reproduction case
- [x] Existing stdin/tty tests still pass
(`tty-readstream-ref-unref.test.ts`,
`tty-reopen-after-stdin-eof.test.ts`)
## Reproduction
Before this fix, the following code would exit immediately:
```ts
process.stdin.on("data", chunk => {
process.stdout.write(chunk);
});
process.stdin.pause();
process.stdin.resume();
```
After the fix, it correctly waits for and processes input.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
1.5 KiB
1.5 KiB