mirror of
https://github.com/euzu/tuliprox.git
synced 2026-10-26 08:42:16 +01:00
Merge pull request #418 from DarkBreakpoint/fix/file-lock-owned-guards
refactor: swap file lock transmutes for owned guards to remove unsafe hack
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
use std::collections::HashMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use std::{fmt, io};
|
||||
use std::path::{Path, PathBuf};
|
||||
use tokio::sync::{Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
use tokio::sync::{OwnedRwLockReadGuard, OwnedRwLockWriteGuard};
|
||||
use shared::error::str_to_io_error;
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -20,26 +21,22 @@ impl FileLockManager {
|
||||
// Acquires a read lock for the specified file and returns a FileReadGuard.
|
||||
pub async fn read_lock(&self, path: &Path) -> FileReadGuard {
|
||||
let file_lock = self.get_or_create_lock(path).await;
|
||||
let guard = file_lock.read().await;
|
||||
// Clone the Arc to avoid moving `file_lock` out, as it is still borrowed by `guard`
|
||||
FileReadGuard::new(Arc::clone(&file_lock), guard)
|
||||
let guard = Arc::clone(&file_lock).read_owned().await;
|
||||
FileReadGuard::new(guard)
|
||||
}
|
||||
|
||||
// Acquires a write lock for the specified file and returns a FileWriteGuard.
|
||||
pub async fn write_lock(&self, path: &Path) -> FileWriteGuard {
|
||||
let file_lock = self.get_or_create_lock(path).await;
|
||||
let guard = file_lock.write().await;
|
||||
// Clone the Arc to avoid moving `file_lock` out, as it is still borrowed by `guard`
|
||||
FileWriteGuard::new(Arc::clone(&file_lock), guard)
|
||||
let guard = Arc::clone(&file_lock).write_owned().await;
|
||||
FileWriteGuard::new(guard)
|
||||
}
|
||||
|
||||
// Tries to acquire a write lock for the specified file and returns a FileWriteGuard.
|
||||
pub async fn try_write_lock(&self, path: &Path) -> io::Result<FileWriteGuard> {
|
||||
let file_lock = self.get_or_create_lock(path).await;
|
||||
let guard = file_lock.try_write();
|
||||
match guard {
|
||||
// Clone the Arc to avoid moving `file_lock` out, as it is still borrowed by `guard`
|
||||
Ok(lock_guard) => Ok(FileWriteGuard::new(Arc::clone(&file_lock), lock_guard)),
|
||||
match Arc::clone(&file_lock).try_write_owned() {
|
||||
Ok(lock_guard) => Ok(FileWriteGuard::new(lock_guard)),
|
||||
Err(_) => Err(str_to_io_error("Failed to acquire write lock"))
|
||||
}
|
||||
}
|
||||
@@ -75,39 +72,25 @@ impl fmt::Debug for FileLockManager {
|
||||
}
|
||||
|
||||
// Define FileReadGuard to hold both the lock reference and the actual read guard.
|
||||
#[derive(Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct FileReadGuard {
|
||||
lock: Arc<RwLock<()>>,
|
||||
guard: Arc<RwLockReadGuard<'static, ()>>,
|
||||
_guard: OwnedRwLockReadGuard<()>,
|
||||
}
|
||||
|
||||
impl FileReadGuard {
|
||||
pub fn new(lock: Arc<RwLock<()>>, guard: RwLockReadGuard<'_, ()>) -> Self {
|
||||
// Convert the lifetime of `guard` to 'static by transmuting.
|
||||
let static_guard: RwLockReadGuard<'static, ()> = unsafe { std::mem::transmute(guard) };
|
||||
Self {
|
||||
lock,
|
||||
guard: Arc::new(static_guard),
|
||||
}
|
||||
fn new(guard: OwnedRwLockReadGuard<()>) -> Self {
|
||||
Self { _guard: guard }
|
||||
}
|
||||
}
|
||||
|
||||
// Define FileWriteGuard to hold both the lock reference and the actual write guard.
|
||||
#[derive(Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct FileWriteGuard {
|
||||
lock: Arc<RwLock<()>>,
|
||||
guard: Arc<RwLockWriteGuard<'static, ()>>,
|
||||
_guard: OwnedRwLockWriteGuard<()>,
|
||||
}
|
||||
|
||||
impl FileWriteGuard {
|
||||
pub fn new(lock: Arc<RwLock<()>>, guard: RwLockWriteGuard<'_, ()>) -> Self {
|
||||
// Convert the lifetime of `guard` to 'static by transmuting.
|
||||
let static_guard: RwLockWriteGuard<'static, ()> = unsafe { std::mem::transmute(guard) };
|
||||
Self {
|
||||
lock,
|
||||
guard: Arc::new(static_guard),
|
||||
}
|
||||
fn new(guard: OwnedRwLockWriteGuard<()>) -> Self {
|
||||
Self { _guard: guard }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user