Skip to content

Commit 34cdb90

Browse files
mhalkcursoragent
andcommitted
[CI] Add semaphore isolation helper to avoid hangs
Fix possible stale semaphores during parallel runs - isolate semaphores per test run - steal semaphore after timeout Issue: Semaphores including hostnames, which in turn include uppercase letters, are not reaped correctly. This lead to hangs of CI runs. Very recent parallel versions 20260522 and newer handle this case by converting hostname to lowercase: https://cgit.git.savannah.gnu.org/cgit/parallel.git/tree/src/parallel?h=20260522#n7565 Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent bdf8c39 commit 34cdb90

2 files changed

Lines changed: 32 additions & 0 deletions

File tree

bin/semaphore_isolation.src

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# shellcheck shell=bash
2+
#
3+
# semaphore_isolation.src - shared helper for GNU parallel's "sem" semaphore.
4+
#
5+
# Source this file and call isolate_semaphore before any "sem" use. It gives
6+
# "sem" a private, self-cleaning semaphore namespace (its own PARALLEL_HOME) so
7+
# that a leaked/stale token can neither deadlock a run nor leak across runs, and
8+
# optionally bounds a stuck semaphore with a timeout.
9+
#
10+
# Background: on hosts whose name contains uppercase letters, GNU parallel's
11+
# dead-lock reaper (remove_dead_locks) never matches its own token files, so a
12+
# token left behind by an unclean death is never reclaimed and every later
13+
# "sem --wait" deadlocks. A per-run private namespace sidesteps this entirely.
14+
#
15+
# Design:
16+
# - No-op when PARALLEL_HOME is already set, so an outer caller never collides.
17+
# - AOMP_SEMAPHORE_TIMEOUT (seconds), if set, is passed to every "sem" call as
18+
# --semaphoretimeout: a wedged sem/sem --wait then steals and proceeds
19+
# instead of hanging. Left unset => pure isolation, no timeout.
20+
21+
isolate_semaphore() {
22+
[ -n "${PARALLEL_HOME:-}" ] && return 0
23+
_semaphore_home=$(mktemp -d "${TMPDIR:-/tmp}/aomp-sem.XXXXXX") || return 0
24+
export PARALLEL_HOME="$_semaphore_home"
25+
if [ -n "${AOMP_SEMAPHORE_TIMEOUT:-}" ]; then
26+
export PARALLEL="--semaphoretimeout ${AOMP_SEMAPHORE_TIMEOUT}${PARALLEL:+ $PARALLEL}"
27+
fi
28+
trap 'rm -rf "$_semaphore_home"' EXIT
29+
}

test/smoke/check_smoke.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ if [ "$AOMP_PARALLEL_SMOKE" == 1 ]; then
227227
fi
228228
sem --help > /dev/null
229229
if [ $? -eq 0 ]; then
230+
# Give "sem" a private, self-cleaning semaphore namespace (no-op if the
231+
# caller already set PARALLEL_HOME). Prevents stale-token deadlocks/leaks.
232+
source "${path}/../../bin/semaphore_isolation.src" 2>/dev/null && isolate_semaphore
230233
COMP_THREADS=1
231234
MAX_THREADS=16
232235
if [ ! -z `which "getconf"` ]; then

0 commit comments

Comments
 (0)