use std::fs::{File, OpenOptions};
use std::path::Path;
use fs4::fs_std::FileExt;
pub struct InstanceLock {
_file: File,
}
pub fn acquire(data_dir: &Path) -> std::io::Result<Option<InstanceLock>> {
std::fs::create_dir_all(data_dir)?;
let file = OpenOptions::new().read(true).write(true).create(true).truncate(false).open(data_dir.join("instance.lock"))?;
match file.try_lock_exclusive() {
Ok(true) => Ok(Some(InstanceLock { _file: file })),
Ok(false) => Ok(None),
Err(e) if e.kind() == std::io::ErrorKind::WouldBlock => Ok(None),
Err(e) => Err(e),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn second_lock_fails_until_released() {
let dir = tempfile::tempdir().unwrap();
let first = acquire(dir.path()).unwrap();
assert!(first.is_some());
assert!(acquire(dir.path()).unwrap().is_none());
drop(first);
assert!(acquire(dir.path()).unwrap().is_some());
}
}