Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

termio/exec: fix 100% CPU usage after wait-after-command process exits #4171

Merged
merged 1 commit into from
Jan 8, 2025

Conversation

kdrag0n
Copy link
Contributor

@kdrag0n kdrag0n commented Dec 31, 2024

read(2) returning 0 means that the other end of the pipe/pty has been
closed (EOF), so there cannot be any more output to read on the pipe, and
the io reader thread can just exit.

If exec.wait_after_command=false, the read thread's quit pipe is
immediately written to after the child process dies, so all is well.
However, if wait_after_command=true (which is the case when using Ghostty
to run a .command/.sh file on macOS), the read thread keeps spinning,
causing persistent 100% CPU usage per exited process.

Fix it by exiting the reader thread on EOF.

@mitchellh
Copy link
Contributor

I haven't looked into it more closely, but I'm still seeing 100% CPU usage even with your changes in.

Reproduction:

  1. zig build run -Dapp-runtime=glfw -- --wait-after-command=true
  2. Type exit in the launched window
  3. See CPU usage

@mitchellh
Copy link
Contributor

Oh, my rebase... removed your change. Looking at it now.

If the read thread has already exited, it will have closed the read end
of the quit pipe. Unless SIGPIPE is masked with signal(SIGPIPE, SIG_IGN),
or the macOS-specific fcntl(F_SETNOSIGPIPE), writing to the write end of
a broken pipe kills the writer with SIGPIPE instead of returning -EPIPE
as an error. This causes a crash if the read thread exits before
threadExit.

This was already a possible race condition if read() returns
error.NotOpenForReading or error.InputOutput, but it's now much easier to
trigger due to the recent "termio/exec: fix 100% CPU usage after
wait-after-command process exits" fix.

Fix this by closing the quit pipe instead of writing to it.
@mitchellh
Copy link
Contributor

Alright this looks clean to me. Thank you

@mitchellh mitchellh disabled auto-merge January 8, 2025 21:10
@mitchellh mitchellh merged commit 6f720a0 into ghostty-org:main Jan 8, 2025
24 checks passed
@github-actions github-actions bot added this to the 1.1.0 milestone Jan 8, 2025
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