use anyhow::Context;
use fslock::{
IntoOsString,
LockFile,
ToOsStr,
};
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct AsyncLockFile {
file: Arc<tokio::sync::Mutex<LockFile>>,
}
impl AsyncLockFile {
pub async fn open<P>(path: P) -> anyhow::Result<Self>
where
P: IntoOsString,
{
let path = path.into_os_string()?;
tokio::task::spawn_blocking(move || Self::blocking_open(&path))
.await
.context("failed to join task")?
}
pub fn blocking_open<P>(path: &P) -> anyhow::Result<Self>
where
P: ToOsStr + ?Sized,
{
let file = LockFile::open(path)?;
Ok(Self {
file: Arc::new(tokio::sync::Mutex::new(file)),
})
}
pub async fn lock(&self) -> anyhow::Result<()> {
let mut file = self.file.clone().lock_owned().await;
Ok(tokio::task::spawn_blocking(move || file.lock())
.await
.context("failed to join task")??)
}
pub async fn lock_with_pid(&self) -> anyhow::Result<()> {
let mut file = self.file.clone().lock_owned().await;
Ok(tokio::task::spawn_blocking(move || file.lock_with_pid())
.await
.context("failed to join task")??)
}
pub async fn try_lock(&self) -> anyhow::Result<bool> {
let mut file = self.file.clone().lock_owned().await;
Ok(tokio::task::spawn_blocking(move || file.try_lock())
.await
.context("failed to join task")??)
}
pub async fn try_lock_with_pid(&self) -> anyhow::Result<bool> {
let mut file = self.file.clone().lock_owned().await;
Ok(
tokio::task::spawn_blocking(move || file.try_lock_with_pid())
.await
.context("failed to join task")??,
)
}
pub fn try_lock_with_pid_blocking(&self) -> anyhow::Result<bool> {
Ok(self.file.blocking_lock().try_lock_with_pid()?)
}
pub async fn owns_lock(&self) -> anyhow::Result<bool> {
let file = self.file.clone().lock_owned().await;
tokio::task::spawn_blocking(move || file.owns_lock())
.await
.context("failed to join task")
}
pub async fn unlock(&self) -> anyhow::Result<()> {
let mut file = self.file.clone().lock_owned().await;
Ok(tokio::task::spawn_blocking(move || file.unlock())
.await
.context("failed to join task")??)
}
pub fn blocking_unlock(&self) -> anyhow::Result<()> {
Ok(self.file.blocking_lock().unlock()?)
}
}