summaryrefslogtreecommitdiffstats
path: root/crates/common/flockfile/src/unix.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/common/flockfile/src/unix.rs')
-rw-r--r--crates/common/flockfile/src/unix.rs70
1 files changed, 38 insertions, 32 deletions
diff --git a/crates/common/flockfile/src/unix.rs b/crates/common/flockfile/src/unix.rs
index 28646601..72fe1260 100644
--- a/crates/common/flockfile/src/unix.rs
+++ b/crates/common/flockfile/src/unix.rs
@@ -5,7 +5,9 @@ use std::{
os::unix::io::AsRawFd,
path::{Path, PathBuf},
};
-use tracing::{debug, error, warn};
+use tracing::{debug, error, info, warn};
+
+const LOCK_CHILD_DIRECTORY: &str = "lock/";
#[derive(thiserror::Error, Debug)]
pub enum FlockfileError {
@@ -24,6 +26,15 @@ pub enum FlockfileError {
},
}
+impl FlockfileError {
+ fn path(&self) -> &Path {
+ match self {
+ FlockfileError::FromIo { path, .. } => path,
+ FlockfileError::FromNix { path, .. } => path,
+ }
+ }
+}
+
/// flockfile creates a lockfile in the filesystem under `/run/lock` and then creates a filelock using system fcntl with flock.
/// flockfile will automatically remove lockfile on application exit and the OS should cleanup the filelock afterwards.
/// If application exits unexpectedly the filelock will be dropped, but the lockfile will not be removed unless handled in signal handler.
@@ -40,29 +51,26 @@ impl Flockfile {
///
/// let _lockfile = match flockfile::Flockfile::new_lock("app")).unwrap();
///
- pub fn new_lock(lock_name: impl AsRef<Path>) -> Result<Flockfile, FlockfileError> {
- let path = Path::new("/run/lock").join(lock_name);
-
- let file = match OpenOptions::new()
+ pub fn new_lock(path: impl AsRef<Path>) -> Result<Flockfile, FlockfileError> {
+ let path = PathBuf::new().join(path);
+ let file = OpenOptions::new()
.create(true)
.read(true)
.write(true)
.open(&path)
- {
- Ok(file) => file,
- Err(err) => {
- return Err(FlockfileError::FromIo { path, source: err });
- }
- };
-
- let () = match flock(file.as_raw_fd(), FlockArg::LockExclusiveNonblock) {
- Ok(()) => (),
- Err(err) => {
- return Err(FlockfileError::FromNix { path, source: err });
+ .map_err(|err| FlockfileError::FromIo {
+ path: path.clone(),
+ source: err,
+ })?;
+
+ flock(file.as_raw_fd(), FlockArg::LockExclusiveNonblock).map_err(|err| {
+ FlockfileError::FromNix {
+ path: path.clone(),
+ source: err,
}
- };
+ })?;
- debug!(r#"Lockfile created "{:?}""#, &path);
+ info!(r#"Lockfile created {:?}"#, &path);
Ok(Flockfile {
handle: Some(file),
path,
@@ -104,20 +112,18 @@ impl AsRef<Path> for Flockfile {
}
}
-/// Check /run/lock/ for a lock file of a given `app_name`
-pub fn check_another_instance_is_not_running(app_name: &str) -> Result<Flockfile, FlockfileError> {
- match Flockfile::new_lock(format!("{}.lock", app_name)) {
- Ok(file) => Ok(file),
- Err(err) => {
- return match &err {
- FlockfileError::FromIo { path, .. } | FlockfileError::FromNix { path, .. } => {
- error!("Another instance of {} is running.", app_name);
- error!("Lock file path: {}", path.as_path().to_str().unwrap());
- Err(err)
- }
- }
- }
- }
+/// Check `run_dir`/lock/ for a lock file of a given `app_name`
+pub fn check_another_instance_is_not_running(
+ app_name: &str,
+ run_dir: &Path,
+) -> Result<Flockfile, FlockfileError> {
+ let lock_path = run_dir.join(format!("{}{}.lock", LOCK_CHILD_DIRECTORY, app_name));
+
+ Flockfile::new_lock(lock_path.as_path()).map_err(|err| {
+ error!("Another instance of {} is running.", app_name);
+ error!("Lock file path: {}", err.path().to_str().unwrap());
+ err
+ })
}
#[cfg(test)]