Replace flock with mkdir

flock is not supported on MacOS.

`mkdir` locks have a drawback: they are not cleaned up automatically. If the lock owner crashed before cleaning up the lock, the directory will stay in the filesystem and the lock will be never acquired by someone else. To avoid that, we create temporary locks (the lockdir name changes every 100 seconds). We grab two lock (N and N+1) to avoid the case where process A grabs lock N and process B grabs lock N+1 and both enter the critical section.
pull/61/head
v9v 2019-07-08 15:58:42 +02:00 committed by GitHub
parent 10e612d72c
commit 800488ca6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 14 additions and 7 deletions

View File

@ -35,13 +35,20 @@ fetch_and_run_tmux_resurrect_save_script() {
}
main() {
(
# The code after "flock" is not thread-safe. A race condition can be triggered by multiple
# tmux clients performing autosave in parallel.
! command -v flock || flock -n 101 || return
if supported_tmux_version_ok && auto_save_not_disabled && enough_time_since_last_run_passed; then
fetch_and_run_tmux_resurrect_save_script
# Sometimes tmux starts multiple saves in parallel. We want only one
# save to be running, otherwise we can get corrupted saved state.
# The following implements a lock that auto-expires after 100...200s.
local lockdir_prefix="/tmp/tmux-continuum-$(current_tmux_server_pid)-lock-"
local lockdir1="${lockdir_prefix}$[ `date +%s` / 100 ]"
local lockdir2="${lockdir_prefix}$[ `date +%s` / 100 + 1]"
if mkdir "$lockdir1"; then
trap "rmdir "$lockdir1"" EXIT
if mkdir "$lockdir2"; then
trap "rmdir "$lockdir1" "$lockdir2"" EXIT
if supported_tmux_version_ok && auto_save_not_disabled && enough_time_since_last_run_passed; then
fetch_and_run_tmux_resurrect_save_script
fi
fi
) 101>/tmp/tmux-continuum-autosave.lockfile
fi
}
main