11debfc3dSmrg#! /bin/sh 2*8feb0f0bSmrg# Shell-based mutex using mkdir. This script is used in make to prefer 3*8feb0f0bSmrg# serialized execution to avoid consuming too much RAM. If reusing it, 4*8feb0f0bSmrg# bear in mind that the lock-breaking logic is not race-free, so disable 5*8feb0f0bSmrg# it in err() if concurrent execution could cause more serious problems. 61debfc3dSmrg 7*8feb0f0bSmrgself=`basename $0` 81debfc3dSmrglockdir="$1" prog="$2"; shift 2 || exit 1 91debfc3dSmrg 101debfc3dSmrg# Remember when we started trying to acquire the lock. 111debfc3dSmrgcount=0 121debfc3dSmrg 13*8feb0f0bSmrgerr () { 14*8feb0f0bSmrg if test -f $lockdir/lock-$1.$$; then 15*8feb0f0bSmrg rm -rf $lockdir 16*8feb0f0bSmrg echo "$self: *** (PID $$) removed stale $lockdir" >&2 17*8feb0f0bSmrg 18*8feb0f0bSmrg # Possible variant for uses where races are more problematic: 19*8feb0f0bSmrg #echo "$self: *** (PID $$) giving up, maybe rm -r $lockdir" >&2 20*8feb0f0bSmrg #exit 42 21*8feb0f0bSmrg else 22*8feb0f0bSmrg touch $lockdir/lock-$1.$$ 23*8feb0f0bSmrg fi 24*8feb0f0bSmrg} 251debfc3dSmrg 261debfc3dSmrguntil mkdir "$lockdir" 2>/dev/null; do 271debfc3dSmrg # Say something periodically so the user knows what's up. 281debfc3dSmrg if [ `expr $count % 30` = 0 ]; then 29*8feb0f0bSmrg # Check for valid lock. 30*8feb0f0bSmrg if pid=`cat $lockdir/pid 2>/dev/null` && kill -0 $pid 2>/dev/null; then 31*8feb0f0bSmrg echo "$self: (PID $$) waiting $count sec to acquire $lockdir from PID $pid" >&2 32*8feb0f0bSmrg elif test -z "$pid"; then 33*8feb0f0bSmrg echo "$self: (PID $$) cannot read $lockdir/pid" >&2 34*8feb0f0bSmrg err nopid 351debfc3dSmrg else 36*8feb0f0bSmrg echo "$self: (PID $$) cannot signal $lockdir owner PID $pid" >&2 37*8feb0f0bSmrg err dead 381debfc3dSmrg fi 391debfc3dSmrg fi 401debfc3dSmrg sleep 1 411debfc3dSmrg count=`expr $count + 1` 421debfc3dSmrgdone 431debfc3dSmrg 44*8feb0f0bSmrgtrap 'rm -rf "$lockdir"' 0 45*8feb0f0bSmrgecho $$ > $lockdir/pidT && mv $lockdir/pidT $lockdir/pid 46*8feb0f0bSmrgecho "$self: (PID $$) acquired $lockdir after $count seconds" >&2 47*8feb0f0bSmrg 481debfc3dSmrgecho $prog "$@" 491debfc3dSmrg$prog "$@" 501debfc3dSmrg 511debfc3dSmrg# The trap runs on exit. 52