about summary refs log tree commit diff
path: root/Functions/Calendar/calendar_lockfiles
diff options
context:
space:
mode:
Diffstat (limited to 'Functions/Calendar/calendar_lockfiles')
-rw-r--r--Functions/Calendar/calendar_lockfiles43
1 files changed, 43 insertions, 0 deletions
diff --git a/Functions/Calendar/calendar_lockfiles b/Functions/Calendar/calendar_lockfiles
new file mode 100644
index 000000000..58ee42114
--- /dev/null
+++ b/Functions/Calendar/calendar_lockfiles
@@ -0,0 +1,43 @@
+# Lock the given files.
+# Append the names of lockfiles to the array lockfiles.
+
+local file lockfile msgdone
+# Number of attempts to lock a file.  Probably not worth stylising.
+integer lockattempts=3
+
+# The lockfile name is not stylised: it has to be a fixed
+# derivative of the main fail.
+for file; do
+  lockfile=$file.lockfile
+  for (( i = 0; i < lockattempts; i++ )); do
+    if ln -s $file $lockfile >/dev/null 2>&1; then
+      lockfiles+=($lockfile)
+      break
+    fi
+    if zle && [[ -z $msgdone ]]; then
+      msgdone="${lockfile}: waiting to acquire lock"
+      zle -M $msgdone
+    fi
+    sleep 1
+  done
+  if [[ -n $msgdone ]]; then
+    zle -M ${msgdone//?/ }
+    msgdone=
+  fi
+  if [[ ${lockfiles[-1]} != $lockfile ]]; then
+    msgdone="Failed to lock $file; giving up after $lockattempts attempts.
+Another instance of calendar may be using it.
+Delete $lockfiles if you believe this to be an error."
+    if zle; then
+      zle -M $msgdone
+    else
+      print $msgdone >&2
+    fi
+    # The parent should take action to delete any lockfiles
+    # already locked.  Typically this won't be necessary, since
+    # we will always lock the main calendar file first.
+    return 1
+  fi
+done
+
+return 0