#!/bin/sh
# Copyright 2010 - 2018 FARGOS Development, LLC
# Create, clear or wait upon a completion lock
# Used to allow shell scripts to enforce mutual exclusion
# $Id$
# NOTE:  nothing in this file requires custom shared libraries
unset LD_LIBRARY_PATH # remove from environment to speed up trivial programs

maxWaitCount=200
interval=5
targetDir=""
doSet=0
doWait=0
doClear=0
quiet=0
fileName="tmp.waitingFor"

while test $# -gt 0
do
	case $1 in
	-h | -help | --help)
printf "usage: %s [{-q | -v}] [--clear] [--wait] [--set] [-i interval] [-t trials] [--dir dirName] [--name fileName]\n" $0 >&2 
		exit 1
		;;
	-wait | --wait)
		doWait=1
		;;
	-set | --set)
		doSet=1
		;;
	-clear | --clear)
		doClear=1
		;;
	-i | -interval | --interval)
		interval=$2
		shift
		;;
	-t | -trials | --trials)
		maxWaitCount=$2
		shift
		;;
	-q | -quiet | --quiet)
		quiet=1
		;;
	-v | -verbose | --verbose)
		quiet=2
		;;
	-name | --name)
		fileName="$2"
		shift
		;;
	-dir | --dir)
		targetDir="$2"
		quiet=1
		shift
		;;
	esac
	shift
done
if test -z "${targetDir}"
then
	if test -n "${STO}"
	then
		targetDir=${STO}`sbrel`
	else
		targetDir=`pwd`
	fi
fi

/bin/mkdir -p ${targetDir}	# parent dir has to exist...

lockFile=${targetDir}/${fileName}

if test ${quiet} -ne 1
then
	echo Operating on ${lockFile} `date`
fi
if test ${doClear} -eq 1
then
	/bin/rm -f ${lockFile}/tmp.envState
	/bin/rmdir ${lockFile}
	exit 0
fi

retryWait=`expr ${doWait} + ${doSet}`

while test ${retryWait} -gt 0
do
	retryWait=0 # assume we won't retry
	if test ${doWait} -eq 1
	then
		waitCount=0
		startSeconds=`date +%s`
		elapsedTime=0
		while test -e ${lockFile}
		do
			if test ${waitCount} -gt ${maxWaitCount}
			then
				printf "%s: waited too long for %s elapsed=%d seconds\n" $0 ${lockFile} ${elapsedTime} >&2
				exit 1	# exit with error indication
			fi
			waitCount=`expr ${waitCount} + 1`
			if test ${waitCount} -gt 2
			then
				printf "%s: still waiting on %s, pass %d, seconds %d\n" $0 ${lockFile} ${waitCount} ${elapsedTime} >&2
			fi
			sleep ${interval}
			nowSeconds=`date +%s`
			elapsedTime=`expr ${nowSeconds} - ${startSeconds}`
		done
		if test ${waitCount} -ne 0
		then
			printf "%s: had to wait for %d intervals on %s elapsedSeconds=%d\n" $0 ${waitCount} ${lockFile} ${elapsedTime} >&2
		fi
	fi

	if test ${doSet} -ne 0
	then
		/bin/mkdir ${lockFile}
		rc=$? # save exit status
		if test ${rc} -eq 0
		then # mkdir succeeded
			env > ${lockFile}/tmp.envState
			doSet=0 # all done
		else # very, very, very rare race condition possibility
			# someone just created it
			printf "%s: could not make lock %s\n" $0 ${lockFile} >&2
			if test ${doWait} -ne 1
			then
				printf "%s: lock file already exists, but no wait %s\n" $0 ${lockFile} >&2
				exit 1	# exit with error indication
			fi
			retryWait=1
		fi
	fi
done
exit 0
