From 25dd546d42460e7f79ace4ad64b7f34a1d332050 Mon Sep 17 00:00:00 2001 From: ironerumi <39033099+ironerumi@users.noreply.github.com> Date: Fri, 9 Oct 2026 02:40:31 +0900 Subject: [PATCH 1/2] test: order stale watcher-lock fixture races explicitly --- tests/fm-watcher-lock.test.sh | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/tests/fm-watcher-lock.test.sh b/tests/fm-watcher-lock.test.sh index 75f8a4291b0..a6f26bb0736 100755 --- a/tests/fm-watcher-lock.test.sh +++ b/tests/fm-watcher-lock.test.sh @@ -516,6 +516,9 @@ test_lock_steal_reap_cannot_remove_successor() { fakebin="$dir/fakebin" out="$dir/competitor" leave_dead_link_locks "$state" "$steal" + # The killed fixture owner may have its PID reused during a loaded serial + # shard. Pin a verified-dead PID so the race exercises reaping, not liveness. + printf '%s\n' "$(dead_pid)" > "$steal/pid" cat > "$fakebin/rm" <<'SH' #!/usr/bin/env bash last= @@ -544,6 +547,7 @@ SH FM_TEST_RACE_ONCE="$dir/race-once" FM_TEST_RACE_OUT="$out" \ FM_STATE_OVERRIDE="$state" bash -c ' . "$1" + fm_lock_reap_dead_link "$2" || exit 1 fm_lock_try_acquire_steal_mutex "$2" || exit 1 [ "$(cat "$2/pid" 2>/dev/null)" = "${BASHPID:-$$}" ] || exit 2 ' _ "$LIB" "$steal" || rc=$? @@ -562,32 +566,51 @@ SH } test_lock_stale_steal_single_winner_under_concurrency() { - local dir state lockdir dead marker i pids pid wins + local dir state lockdir dead marker gate hold i pids pid waiter winner wins dir=$(make_case lock-stale-concurrency) state="$dir/state" lockdir="$state/.contend.lock" marker="$dir/wins" + gate="$dir/first-winner" + hold="$dir/winner-release" dead=$(dead_pid) mkdir "$lockdir" printf '%s\n' "$dead" > "$lockdir/pid" : > "$marker" + mkfifo "$gate" "$hold" + # try_acquire is nonblocking: all one-shot candidates may lose to a transient + # steal mutex. A waiting contender guarantees eventual acquisition, and the + # FIFO keeps the winner alive until every other contender has finished. + FM_STATE_OVERRIDE="$state" bash -c ' + . "$1" + fm_lock_acquire_wait "$2" || exit 1 + printf "%s\n" "${BASHPID:-$$}" >> "$3" + printf "%s\n" "${BASHPID:-$$}" > "$4" + IFS= read -r _ < "$5" + ' _ "$LIB" "$lockdir" "$marker" "$gate" "$hold" & + waiter=$! pids= i=1 - while [ "$i" -le 40 ]; do + while [ "$i" -le 39 ]; do FM_STATE_OVERRIDE="$state" bash -c ' . "$1" if fm_lock_try_acquire "$2"; then printf "%s\n" "${BASHPID:-$$}" >> "$3" - sleep 1 + printf "%s\n" "${BASHPID:-$$}" > "$4" + IFS= read -r _ < "$5" fi - ' _ "$LIB" "$lockdir" "$marker" & + ' _ "$LIB" "$lockdir" "$marker" "$gate" "$hold" & pids="$pids $!" i=$((i + 1)) done + IFS= read -r winner < "$gate" + [ "$winner" = "$waiter" ] || { kill "$waiter" 2>/dev/null || true; wait "$waiter" 2>/dev/null || true; } for pid in $pids; do - wait "$pid" 2>/dev/null || true + [ "$pid" = "$winner" ] || wait "$pid" 2>/dev/null || true done wins=$(awk 'NF { c++ } END { print c + 0 }' "$marker") + printf 'release\n' > "$hold" + wait "$winner" 2>/dev/null || true [ "$wins" -eq 1 ] || fail "expected exactly one stale-lock stealer, got $wins" pass "concurrent stale-lock steal yields exactly one winner" } From d834b26519de4d7420cbf19fde73d25023bdeb83 Mon Sep 17 00:00:00 2001 From: ironerumi <39033099+ironerumi@users.noreply.github.com> Date: Fri, 9 Oct 2026 02:53:02 +0900 Subject: [PATCH 2/2] no-mistakes(review): Removed duplicate stale-steal reap call --- tests/fm-watcher-lock.test.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/fm-watcher-lock.test.sh b/tests/fm-watcher-lock.test.sh index a6f26bb0736..cf985d9bc23 100755 --- a/tests/fm-watcher-lock.test.sh +++ b/tests/fm-watcher-lock.test.sh @@ -547,7 +547,6 @@ SH FM_TEST_RACE_ONCE="$dir/race-once" FM_TEST_RACE_OUT="$out" \ FM_STATE_OVERRIDE="$state" bash -c ' . "$1" - fm_lock_reap_dead_link "$2" || exit 1 fm_lock_try_acquire_steal_mutex "$2" || exit 1 [ "$(cat "$2/pid" 2>/dev/null)" = "${BASHPID:-$$}" ] || exit 2 ' _ "$LIB" "$steal" || rc=$?