just playing with tangled
1// Copyright 2020 The Jujutsu Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fs::{File, OpenOptions};
16use std::path::PathBuf;
17use std::time::Duration;
18
19use backoff::{retry, ExponentialBackoff};
20use tracing::instrument;
21
22pub struct FileLock {
23 path: PathBuf,
24 _file: File,
25}
26
27impl FileLock {
28 pub fn lock(path: PathBuf) -> FileLock {
29 let mut options = OpenOptions::new();
30 options.create_new(true);
31 options.write(true);
32 let try_write_lock_file = || match options.open(&path) {
33 Ok(file) => Ok(FileLock {
34 path: path.clone(),
35 _file: file,
36 }),
37 Err(err) if err.kind() == std::io::ErrorKind::AlreadyExists => {
38 Err(backoff::Error::Transient {
39 err,
40 retry_after: None,
41 })
42 }
43 Err(err) if cfg!(windows) && err.kind() == std::io::ErrorKind::PermissionDenied => {
44 Err(backoff::Error::Transient {
45 err,
46 retry_after: None,
47 })
48 }
49 Err(err) => Err(backoff::Error::Permanent(err)),
50 };
51 let backoff = ExponentialBackoff {
52 initial_interval: Duration::from_millis(1),
53 max_elapsed_time: Some(Duration::from_secs(10)),
54 ..Default::default()
55 };
56 match retry(backoff, try_write_lock_file) {
57 Err(err) => panic!(
58 "failed to create lock file {}: {}",
59 path.to_string_lossy(),
60 err
61 ),
62 Ok(file_lock) => file_lock,
63 }
64 }
65}
66
67impl Drop for FileLock {
68 #[instrument(skip_all)]
69 fn drop(&mut self) {
70 std::fs::remove_file(&self.path).expect("failed to delete lock file");
71 }
72}