use std::{
collections::HashMap,
path::{Path, PathBuf},
sync::{Arc, Mutex, RwLock},
};
use crate::{AbsolutePath, Result};
#[derive(Debug, Default)]
pub struct PathSync {
locks: Arc<RwLock<HashMap<PathBuf, Arc<Mutex<()>>>>>,
}
impl PathSync {
pub fn new() -> Self {
Self {
locks: Arc::new(RwLock::new(HashMap::new())),
}
}
pub fn with_sync_path(
&self,
path: &Path,
mut f: impl FnMut(&Path) -> Result<()>,
) -> Result<()> {
let entry = {
let locks = self.locks.clone();
let mut locks = locks.write()?;
locks
.entry(path.to_path_buf())
.or_insert_with(|| Arc::new(Mutex::new(())))
.clone()
};
let _guard = entry.lock()?;
f(path)?;
Ok(())
}
pub fn with_sync_abs_path(
&self,
path: &AbsolutePath,
mut f: impl FnMut(&AbsolutePath) -> Result<()>,
) -> Result<()> {
{
let entry = {
let locks = self.locks.clone();
let mut locks = locks.write()?;
locks
.entry(path.to_path_buf())
.or_insert_with(|| Arc::new(Mutex::new(())))
.clone()
};
let _guard = entry.lock()?;
f(path)?;
}
Ok(())
}
}
pub type PathSyncSingleton = Arc<Mutex<PathSync>>;