Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/rust/src/lock.rs
2885 views
1
// Licensed to the Software Freedom Conservancy (SFC) under one
2
// or more contributor license agreements. See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership. The SFC licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License. You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied. See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
use crate::logger::Logger;
19
use anyhow::Error;
20
use std::cell::RefCell;
21
use std::fs::File;
22
use std::path::{Path, PathBuf};
23
24
use crate::files::{create_parent_path_if_not_exists, create_path_if_not_exists};
25
use fs2::FileExt;
26
use std::fs;
27
28
thread_local!(static LOCK_PATH: RefCell<Option<PathBuf>> = const { RefCell::new(None) });
29
30
const LOCK_FILE: &str = "sm.lock";
31
32
pub struct Lock {
33
file: File,
34
path: PathBuf,
35
}
36
37
impl Lock {
38
// Acquire file lock to prevent race conditions accessing the cache folder by concurrent SM processes
39
pub fn acquire(
40
log: &Logger,
41
target: &Path,
42
single_file: Option<String>,
43
) -> Result<Self, Error> {
44
let lock_folder = if single_file.is_some() {
45
create_parent_path_if_not_exists(target)?;
46
target.parent().unwrap()
47
} else {
48
create_path_if_not_exists(target)?;
49
target
50
};
51
let path = lock_folder.join(LOCK_FILE);
52
let file = File::create(&path)?;
53
54
log.debug(format!("Acquiring lock: {}", path.display()));
55
file.lock_exclusive().unwrap_or_default();
56
set_lock_path(Some(path.to_path_buf()));
57
58
Ok(Self { file, path })
59
}
60
61
pub fn release(&mut self) {
62
fs::remove_file(&self.path).unwrap_or_default();
63
self.file.unlock().unwrap_or_default();
64
set_lock_path(None);
65
}
66
67
pub fn exists(&mut self) -> bool {
68
self.path.exists()
69
}
70
}
71
72
pub fn clear_lock_if_required() {
73
let lock_path = get_lock_path();
74
if lock_path.is_some() {
75
let lock = lock_path.unwrap();
76
if lock.exists() {
77
fs::remove_file(lock).unwrap_or_default();
78
}
79
}
80
}
81
82
fn set_lock_path(path: Option<PathBuf>) {
83
LOCK_PATH.with(|lock_path| {
84
*lock_path.borrow_mut() = path;
85
});
86
}
87
88
fn get_lock_path() -> Option<PathBuf> {
89
LOCK_PATH.with(|lock_path| lock_path.borrow().clone())
90
}
91
92