When implementing cross-process synchronization with filesystem primitives (e.g. mkdir as a mutex), avoid time-of-check-to-time-of-use races between detecting a stale lock and acting on it. Treat lock recovery as its own critical section:
mkdir lock/reclaim) so only one contender can attempt recovery, then re-read and re-verify the owner identity after the claim and immediately before any destructive action.cd-ing into them for recovery; verify directory identity with something like [[ "$lock" -ef . ]] before deleting, since relative paths can silently resolve to the wrong location once the working directory changes.trap ... EXIT INT TERM to release owned locks and remove partial/temporary artifacts, and add regression tests that simulate concurrent contenders racing to acquire/reclaim the same lock to catch these races before they ship.Example pattern for a safe reclaim:
if [[ "$stale" == true ]]; then
(
cd "$lock" 2>/dev/null || exit 0
mkdir reclaim 2>/dev/null || exit 0 # atomic claim to recover
current=$(cat owner 2>/dev/null || true)
# re-verify the owner is still abandoned AND we're still looking
# at the same directory before destroying anything
[[ "$current" == "$previous" && "$lock" -ef . ]] && rm -rf "$lock"
)
fi
This pattern — atomic claim, re-verify, then act — generalizes to any manually-implemented lock/mutex and should be applied whenever recovery or cleanup logic runs concurrently with other potential lock holders.