Path: blob/main/crates/polars-io/src/file_cache/file_lock.rs
6939 views
use std::fs::{File, OpenOptions};1use std::path::Path;23use fs4::fs_std::FileExt;45/// Note: this creates the file if it does not exist when acquiring locks.6pub(super) struct FileLock<T: AsRef<Path>>(T);7pub(super) struct FileLockSharedGuard(File);8pub(super) struct FileLockExclusiveGuard(File);910/// Trait to specify a file is lock-guarded without needing a particular type of11/// guard (i.e. shared/exclusive).12pub(super) trait FileLockAnyGuard:13std::ops::Deref<Target = File> + std::ops::DerefMut<Target = File>14{15const IS_EXCLUSIVE: bool;16}17impl FileLockAnyGuard for FileLockSharedGuard {18const IS_EXCLUSIVE: bool = false;19}20impl FileLockAnyGuard for FileLockExclusiveGuard {21const IS_EXCLUSIVE: bool = true;22}2324impl<T: AsRef<Path>> From<T> for FileLock<T> {25fn from(path: T) -> Self {26Self(path)27}28}2930impl<T: AsRef<Path>> FileLock<T> {31pub(super) fn acquire_shared(&self) -> Result<FileLockSharedGuard, std::io::Error> {32let file = OpenOptions::new()33.create(true)34.truncate(false)35.read(true)36.write(true)37.open(self.0.as_ref())?;38FileExt::lock_shared(&file).map(|_| FileLockSharedGuard(file))39}4041pub(super) fn acquire_exclusive(&self) -> Result<FileLockExclusiveGuard, std::io::Error> {42let file = OpenOptions::new()43.create(true)44.truncate(false)45.read(true)46.write(true)47.open(self.0.as_ref())?;48file.lock_exclusive().map(|_| FileLockExclusiveGuard(file))49}50}5152impl std::ops::Deref for FileLockSharedGuard {53type Target = File;5455fn deref(&self) -> &Self::Target {56&self.057}58}5960impl std::ops::DerefMut for FileLockSharedGuard {61fn deref_mut(&mut self) -> &mut Self::Target {62&mut self.063}64}6566impl Drop for FileLockSharedGuard {67fn drop(&mut self) {68FileExt::unlock(&self.0).unwrap();69}70}7172impl std::ops::Deref for FileLockExclusiveGuard {73type Target = File;7475fn deref(&self) -> &Self::Target {76&self.077}78}7980impl std::ops::DerefMut for FileLockExclusiveGuard {81fn deref_mut(&mut self) -> &mut Self::Target {82&mut self.083}84}8586impl Drop for FileLockExclusiveGuard {87fn drop(&mut self) {88FileExt::unlock(&self.0).unwrap();89}90}919293