docs(lease): name the double-crash limit of breaking a dead lock

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-17 00:24:20 +00:00
1 parent 1529da1192
commit 390075957a
2 files changed
+7 -2

No files matched your search

+4 -1
View File
@@ -121,7 +121,10 @@ holder_gone() { case "$(state "${1%% *}" "${1#* }" 0)" in dead|stale) return 0 ;
# break_lock OWNER — remove the lock only if it still names OWNER. Breakers
# take a second symlink, .lock.break, and reread the lock under it, so a lock
# taken since the verdict is never removed; a .lock.break whose holder is gone
# is cleared. Returns 1 when another breaker holds .lock.break.
# is cleared. Returns 1 when another breaker holds .lock.break. Known limit:
# that clear is not atomic, so two gstack-lease processes killed in a row (one
# holding .lock, the next inside this function) can let a reclaim delete a
# renewal; one crash is always safe.
break_lock() {
if ! ln -s "$TOKEN" "$LOCK.break" 2>/dev/null; then
_b=$(readlink "$LOCK.break" 2>/dev/null)
+3 -1
View File
@@ -94,7 +94,9 @@ stale) run under one lock in the lease directory, a symlink naming its holder's
pid and start identity, so a renewal is never deleted and a live lease never
disappears from a concurrent scan. The lock is broken only when its holder is
dead or its pid was reused, never by age, and breakers serialize on a second
symlink and reread the lock before removing it. While a live process holds it,
symlink and reread the lock before removing it. One killed gstack-lease process
is always safe; two killed in a row, one holding the lock and the next while
breaking it, can still let a reclaim delete a renewal. While a live process holds it,
`touch` exits 3 without writing (`gstack-skill-start` reports that the
session holds no lease) and a reclaim keeps the lease. `bin/gstack-lease list` shows `alive|dead|stale`, and
`GSTACK_UPGRADE_FORCE=1` overrides.