#!/bin/bash # $HeadURL$ $LastChangedRevision$ echo "setting up environment ..." LOCKFILE=/tmp/x.lock echo "defining support functions ..." devariant() { sed -r 's/[1-9][0-9]*/999999/' "$@" } shell_lock() { adeshf 'ade_lock "$ERRSTACK_REF" /tmp/x.lock || return $?; sleep 10; return $ADE_OK' } perl_lock() { adeperlf '$rc=ADE::lock($errstack_ref, "/tmp/x.lock"); return($rc) if ($rc!=$ADE::OK); sleep(10); return($ADE::OK);' } python_lock() { # '[ x, y, z ][-1]' is the equivalent of C's comma operator: evaluation each item in a list but return the value of the last. # We use it here as a way to turn two statements (sleep and produce-a-value) into a single statement and thereby avoid the # need to indent in a context that doesn't support indentation (i.e. a single line program). adepyf 'import time; import ade; rc=ade.lock(errstack, "/tmp/x.lock"); return rc if rc != ade.ok else [ time.sleep(10), ade.ok ][-1]' } test_valid_locks() { echo "starting $ADELANG version ..." ${ADELANG}_lock & echo "giving $ADELANG version a moment to create its lock ..." sleep 1 devariant $LOCKFILE echo "starting a second $ADELANG version (expect an error) ..." ${ADELANG}_lock 2>&1 | devariant echo "waiting for all $ADELANG version children to exit ..." wait } test_stale_locks() { echo "starting $ADELANG version ..." ${ADELANG}_lock > /dev/null 2>&1 & # Do not use '$!' because that would be the pid of the backgrounded shell # function (i.e. a shell) not of ade{sh,perl,py}f! echo "giving $ADELANG version a moment to create its lock ..." sleep 5 PID=$(cat /tmp/x.lock) if ! [[ $PID =~ ^[1-9][0-9]+$ ]]; then echo "test_stale_locks: lock contents doesn't look like a pid! ($PID)" elif ! [ -d /proc/$PID ]; then echo "test_stale_locks: lock contents pid ($PID) doesn't appear to be running!" else echo "test_stale_locks: killing it ..." kill -9 $PID echo "test_stale_locks: waiting for children to exit ..." wait > /dev/null 2>&1 fi echo "starting it again to see if it sees stale lock (expect a warning) ..." ${ADELANG}_lock & # This sleep serves a double purpose! It ensures the lock file has been # written by the time we come to read it *and* it ensures that the # stale lock warning and the next echo come out in a consistent order. sleep 5 PID=$(cat /tmp/x.lock) if ! [[ $PID =~ ^[1-9][0-9]+$ ]]; then echo "test_stale_locks: lock contents doesn't look like a pid! ($PID)" elif ! [ -d /proc/$PID ]; then echo "test_stale_locks: lock contents pid ($PID) doesn't appear to be running!" else echo "test_stale_locks: waiting for children to exit ..." wait > /dev/null 2>&1 fi } echo "starting test_valid_locks loop (meet valid locks) ..." for ADELANG in shell perl python; do echo "$ADELANG ..." test_valid_locks done echo "starting test_stale_locks loop (meet state locks) ..." for ADELANG in shell perl python; do echo "$ADELANG ..." test_stale_locks done echo "all done"