Skip to main content

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}