fix: prevent PTY leak by detecting orphaned worker processes
When a tmux session is killed (e.g., via `tmux kill-session`), the zshexit hook may not fire, leaving p10k worker and gitstatus daemon processes orphaned (PPID=1). These orphaned processes hold PTY resources indefinitely, eventually causing PTY exhaustion. This fix adds parent process monitoring: 1. worker.zsh: Check PPID in main loop - exit if parent dies 2. gitstatus.plugin.zsh: Add background monitor that detects PPID change to 1 (init/launchd) and triggers cleanup The fix handles the case where shells are terminated without proper cleanup (SIGKILL, tmux kill-session, etc.). Fixes orphaned processes like: - p10k.worker.*.fifo holders - gitstatus.POWERLEVEL9K.*.fifo holders - gitstatusd-darwin-arm64 daemons Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
b97926675a
commit
349cd9b416
|
|
@ -475,6 +475,21 @@ function _gitstatus_daemon"${1:-}"() {
|
||||||
kill -- -$pgid
|
kill -- -$pgid
|
||||||
fi
|
fi
|
||||||
} &!
|
} &!
|
||||||
|
|
||||||
|
# Parent process monitor: detect orphaning and cleanup
|
||||||
|
# This handles cases where zshexit hook doesn't fire (e.g., tmux kill-session)
|
||||||
|
{
|
||||||
|
local orig_ppid=$sysparams[ppid]
|
||||||
|
while true; do
|
||||||
|
command sleep 2
|
||||||
|
# If PPID changed to 1 (init/launchd), parent died - cleanup and exit
|
||||||
|
if [[ $sysparams[ppid] != $orig_ppid ]]; then
|
||||||
|
zf_rm -f -- $file_prefix.lock $file_prefix.fifo
|
||||||
|
kill -- -$pgid 2>/dev/null
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
} &!
|
||||||
}
|
}
|
||||||
|
|
||||||
# Starts gitstatusd in the background. Does nothing and succeeds if gitstatusd is already running.
|
# Starts gitstatusd in the background. Does nothing and succeeds if gitstatusd is already running.
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ function _p9k_worker_main() {
|
||||||
local -A _p9k_worker_fds # fd => id$'\x1f'callback
|
local -A _p9k_worker_fds # fd => id$'\x1f'callback
|
||||||
local -A _p9k_worker_inflight # id => inflight count
|
local -A _p9k_worker_inflight # id => inflight count
|
||||||
|
|
||||||
|
# Store original parent PID to detect orphaning
|
||||||
|
local -i _p9k_worker_orig_ppid=$sysparams[ppid]
|
||||||
|
|
||||||
function _p9k_worker_reply() {
|
function _p9k_worker_reply() {
|
||||||
print -nr -- e${(pj:\n:)@}$'\x1e' || kill -- -$_p9k_worker_pgid
|
print -nr -- e${(pj:\n:)@}$'\x1e' || kill -- -$_p9k_worker_pgid
|
||||||
}
|
}
|
||||||
|
|
@ -24,10 +27,16 @@ function _p9k_worker_main() {
|
||||||
_p9k_worker_fds[$fd]=$_p9k_worker_request_id$'\x1f'$2
|
_p9k_worker_fds[$fd]=$_p9k_worker_request_id$'\x1f'$2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check if parent process is still alive (not orphaned)
|
||||||
|
# If PPID changes to 1 (init/launchd), parent has died
|
||||||
|
function _p9k_worker_check_parent() {
|
||||||
|
[[ $sysparams[ppid] == $_p9k_worker_orig_ppid ]]
|
||||||
|
}
|
||||||
|
|
||||||
trap '' PIPE
|
trap '' PIPE
|
||||||
|
|
||||||
{
|
{
|
||||||
while zselect -a ready 0 ${(k)_p9k_worker_fds}; do
|
while _p9k_worker_check_parent && zselect -a ready 0 ${(k)_p9k_worker_fds}; do
|
||||||
[[ $ready[1] == -r ]] || return
|
[[ $ready[1] == -r ]] || return
|
||||||
for fd in ${ready:1}; do
|
for fd in ${ready:1}; do
|
||||||
if [[ $fd == 0 ]]; then
|
if [[ $fd == 0 ]]; then
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue