Skip to content

Commit b8a7045

Browse files
committed
fix(lock): detect and remove stale locks from killed hook processes
1 parent 29ad0f8 commit b8a7045

2 files changed

Lines changed: 29 additions & 0 deletions

File tree

scripts/remove-rule.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,20 @@ acquire_lock() {
159159
deadline=$(( $(date +%s) + LOCK_TIMEOUT ))
160160
while :; do
161161
if mkdir "$LOCK_DIR" 2>/dev/null; then
162+
printf '%s\n' "$$" > "$LOCK_DIR/pid" 2>/dev/null || true
162163
LOCK_HELD=1
163164
return 0
164165
fi
166+
# Stale lock detection: check if holder PID is still alive.
167+
if [ -f "$LOCK_DIR/pid" ]; then
168+
local holder_pid
169+
holder_pid="$(cat "$LOCK_DIR/pid" 2>/dev/null || true)"
170+
if [ -n "$holder_pid" ] && ! kill -0 "$holder_pid" 2>/dev/null; then
171+
rm -f "$LOCK_DIR/pid" 2>/dev/null || true
172+
rmdir "$LOCK_DIR" 2>/dev/null || true
173+
continue
174+
fi
175+
fi
165176
if [ "$(date +%s)" -ge "$deadline" ]; then
166177
return 1
167178
fi
@@ -171,6 +182,7 @@ acquire_lock() {
171182

172183
release_lock() {
173184
if [ "$LOCK_HELD" -eq 1 ]; then
185+
rm -f "$LOCK_DIR/pid" 2>/dev/null || true
174186
rmdir "$LOCK_DIR" 2>/dev/null || true
175187
LOCK_HELD=0
176188
fi

scripts/write-rule.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,25 @@ acquire_lock() {
117117
deadline=$(( $(date +%s) + LOCK_TIMEOUT ))
118118
while :; do
119119
if mkdir "$LOCK_DIR" 2>/dev/null; then
120+
# Write our PID so stale-lock detection can check liveness.
121+
printf '%s\n' "$$" > "$LOCK_DIR/pid" 2>/dev/null || true
120122
LOCK_HELD=1
121123
return 0
122124
fi
125+
# Stale lock detection: if the lock dir exists but the holder PID is dead,
126+
# forcibly remove it. This handles the case where a hook was killed by
127+
# CC's timeout mid-write, leaving the lock behind.
128+
if [ -f "$LOCK_DIR/pid" ]; then
129+
local holder_pid
130+
holder_pid="$(cat "$LOCK_DIR/pid" 2>/dev/null || true)"
131+
if [ -n "$holder_pid" ] && ! kill -0 "$holder_pid" 2>/dev/null; then
132+
# Holder is dead. Remove stale lock.
133+
rm -f "$LOCK_DIR/pid" 2>/dev/null || true
134+
rmdir "$LOCK_DIR" 2>/dev/null || true
135+
continue # retry mkdir immediately
136+
fi
137+
fi
138+
# No pid file = old-format lock or race. Just wait and retry.
123139
if [ "$(date +%s)" -ge "$deadline" ]; then
124140
return 1
125141
fi
@@ -129,6 +145,7 @@ acquire_lock() {
129145

130146
release_lock() {
131147
if [ "$LOCK_HELD" -eq 1 ]; then
148+
rm -f "$LOCK_DIR/pid" 2>/dev/null || true
132149
rmdir "$LOCK_DIR" 2>/dev/null || true
133150
LOCK_HELD=0
134151
fi

0 commit comments

Comments
 (0)