From 800488ca6f848b7d9269bdcfb435f4bf935eca05 Mon Sep 17 00:00:00 2001 From: v9v <36771847+v9v@users.noreply.github.com> Date: Mon, 8 Jul 2019 15:58:42 +0200 Subject: [PATCH] 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. --- scripts/continuum_save.sh | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/scripts/continuum_save.sh b/scripts/continuum_save.sh index e8c3287..a952cf1 100755 --- a/scripts/continuum_save.sh +++ b/scripts/continuum_save.sh @@ -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