summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Biebl <mbiebl@gmail.com>2010-06-18 15:15:16 +0200
committerVictor Lowther <victor.lowther@gmail.com>2010-07-04 09:42:56 -0500
commit50ec4604c303c0385c981d65d98efd4bb114cd3c (patch)
tree3c60b0892e7cb7c2e6da494f280e041d534f11e2
parente9f516edfbd093c4b9b5721434440e67847f2dd8 (diff)
Use flock for more robust lock file handling
Debian-Bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=568565
-rw-r--r--pm/HOWTO.hooks2
-rw-r--r--pm/functions.in26
2 files changed, 15 insertions, 13 deletions
diff --git a/pm/HOWTO.hooks b/pm/HOWTO.hooks
index ad7d4a7..ce9e8c4 100644
--- a/pm/HOWTO.hooks
+++ b/pm/HOWTO.hooks
@@ -99,7 +99,7 @@ the hook. This will make the following convenience functions available:
2: spin_lock
Wrapper around try_lock. Second parameter is the number of seconds
to wait for the lock before giving up. If no second parameter
- is passed, this function will wait forever.
+ is passed, this function will wait for 60 seconds.
3: release_lock
Release a previously acquired lock. First parameter is the name of the
lock.
diff --git a/pm/functions.in b/pm/functions.in
index 8388c65..b07bf44 100644
--- a/pm/functions.in
+++ b/pm/functions.in
@@ -22,13 +22,13 @@ is_set "${PM_DEBUG}" && set -x
try_lock()
{
# $1 = file to use as lockfile
- # $2 (optional) content to write to the lockfile,
- # extra newline will be appended
+ local lock="${LOCKDIR}/${1##*/}"
+
# make sure the directory where the lockfile should be exists
mkdir -p "${LOCKDIR}"
- local lock="${LOCKDIR}/${1##*/}"
- # we use noclobber to make sure there are no race conditions
- (set -o noclobber; echo "${2}" > "${lock}") 2> /dev/null || return 1
+ touch "${lock}"
+ exec 3<"${lock}"
+ flock -x -n 3 || return 1
return 0
}
@@ -37,13 +37,15 @@ try_lock()
spin_lock()
{
# $1 = lockfile
- # $2 = optional timeout
- local elapsed=0
- while ! try_lock $1; do
- [ "x$2" != "x" ] && [ $(( $elapsed == $2 )) -ne 0 ] && return 1
- elapsed=$(($elapsed + 1))
- sleep 1;
- done
+ # $2 = optional timeout (default is 60 secs)
+ local lock="${LOCKDIR}/${1##*/}"
+ local timeout="${2:-60}"
+
+ mkdir -p "${LOCKDIR}"
+ touch "${lock}"
+ exec 3<"${lock}"
+ flock -x -w "${timeout}" 3 || return 1
+ return 0
}
# release the lock