Skip to content

Instantly share code, notes, and snippets.

@jashmenn
Created November 18, 2008 21:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jashmenn/26283 to your computer and use it in GitHub Desktop.
Save jashmenn/26283 to your computer and use it in GitHub Desktop.
#!/bin/bash
if test $# -lt 1
then
echo "Usage: $0 LOCKDIR cmd"
echo "Example: $0 /var/lock/my_process"
exit
fi
# lock dirs/files
LOCKDIR=$1
shift
#LOCKDIR=/Users/nathan/Desktop/my_lock
PIDFILE="${LOCKDIR}/PID"
# exit codes and text for them - additional features nobody needs :-)
ENO_SUCCESS=0; ETXT[0]="ENO_SUCCESS"
ENO_GENERAL=1; ETXT[1]="ENO_GENERAL"
ENO_LOCKFAIL=2; ETXT[2]="ENO_LOCKFAIL"
ENO_RECVSIG=3; ETXT[3]="ENO_RECVSIG"
###
### start locking attempt
###
trap 'ECODE=$?; echo "[statsgen] Exit: ${ETXT[ECODE]}($ECODE)" >&2' 0
echo -n "[statsgen] Locking: " >&2
if mkdir "${LOCKDIR}" &>/dev/null; then
# lock succeeded, store the PID and install signal handlers
echo "$$" >"${PIDFILE}"
trap 'ECODE=$?;
echo "[statsgen] Removing lock. Exit: ${ETXT[ECODE]}($ECODE)" >&2
rm -rf "${LOCKDIR}"' 0
# the following handler will exit the script on receiving these signals
# the trap on "0" (EXIT) from above will be triggered by this trap's "exit" command!
trap 'echo "[statsgen] Killed by a signal." >&2
exit ${ENO_RECVSIG}' 1 2 3 15
echo "success, installed signal handlers"
echo $@
$@
else
# lock failed, now check if the other PID is alive
OTHERPID="$(cat "${PIDFILE}")"
if ! kill -0 $OTHERPID &>/dev/null; then
# lock is stale, remove it and restart
echo "removing stale lock of nonexistant PID ${OTHERPID}" >&2
rm -rf "${LOCKDIR}"
echo "[statsgen] restarting myself" >&2
exec $0 "$@"
else
# lock is valid and OTHERPID is active - exit, we're locked!
echo "lock failed, PID ${OTHERPID} is active" >&2
exit ${ENO_LOCKFAIL}
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment