chkpt_core/ops/lock.rs
1use std::fs::{File, OpenOptions};
2use std::path::Path;
3
4use fs4::fs_std::FileExt;
5
6use crate::error::{ChkpttError, Result};
7
8/// A file-based project lock that provides mutual exclusion for
9/// save/restore/delete operations.
10///
11/// The lock is held by keeping an exclusive flock on a `project.lock` file.
12/// When the `ProjectLock` is dropped, the file is closed and the lock is
13/// automatically released.
14pub struct ProjectLock {
15 _file: File,
16}
17
18impl ProjectLock {
19 /// Acquire an exclusive project lock.
20 ///
21 /// Creates (or opens) `lock_dir/project.lock` and attempts to take an
22 /// exclusive lock on it. Returns `ChkpttError::LockHeld` if another process
23 /// already holds the lock.
24 pub fn acquire(lock_dir: &Path) -> Result<ProjectLock> {
25 let lock_path = lock_dir.join("project.lock");
26 let file = OpenOptions::new()
27 .create(true)
28 .write(true)
29 .truncate(false)
30 .open(&lock_path)?;
31
32 let acquired = file.try_lock_exclusive()?;
33 if !acquired {
34 return Err(ChkpttError::LockHeld);
35 }
36
37 Ok(ProjectLock { _file: file })
38 }
39}