From b950a6c389f9dde19774a02bf16eb39b5de5201e Mon Sep 17 00:00:00 2001 From: Micha Reiser Date: Wed, 3 Jul 2024 15:12:13 +0200 Subject: [PATCH] Replace `Mutex` with `Mutex` in vendored file system" (#12170) --- crates/ruff_db/src/vendored.rs | 64 +++++++++++----------------------- 1 file changed, 20 insertions(+), 44 deletions(-) diff --git a/crates/ruff_db/src/vendored.rs b/crates/ruff_db/src/vendored.rs index e0fb97754d..d1a4d2f083 100644 --- a/crates/ruff_db/src/vendored.rs +++ b/crates/ruff_db/src/vendored.rs @@ -1,5 +1,4 @@ use std::borrow::Cow; -use std::cell::RefCell; use std::collections::BTreeMap; use std::fmt::{self, Debug}; use std::io::{self, Read}; @@ -13,6 +12,7 @@ pub use path::{VendoredPath, VendoredPathBuf}; pub mod path; type Result = io::Result; +type LockedZipArchive<'a> = MutexGuard<'a, VendoredZipArchive>; /// File system that stores all content in a static zip archive /// bundled as part of the Ruff binary. @@ -20,20 +20,19 @@ type Result = io::Result; /// "Files" in the `VendoredFileSystem` are read-only and immutable. /// Directories are supported, but symlinks and hardlinks cannot exist. pub struct VendoredFileSystem { - inner: VendoredFileSystemInner, + inner: Mutex, } impl VendoredFileSystem { pub fn new(raw_bytes: &'static [u8]) -> Result { Ok(Self { - inner: VendoredFileSystemInner::new(raw_bytes)?, + inner: Mutex::new(VendoredZipArchive::new(raw_bytes)?), }) } pub fn exists(&self, path: &VendoredPath) -> bool { let normalized = NormalizedVendoredPath::from(path); - let inner_locked = self.inner.lock(); - let mut archive = inner_locked.borrow_mut(); + let mut archive = self.lock_archive(); // Must probe the zipfile twice, as "stdlib" and "stdlib/" are considered // different paths in a zip file, but we want to abstract over that difference here @@ -47,13 +46,12 @@ impl VendoredFileSystem { pub fn metadata(&self, path: &VendoredPath) -> Option { let normalized = NormalizedVendoredPath::from(path); - let inner_locked = self.inner.lock(); + let mut archive = self.lock_archive(); // Must probe the zipfile twice, as "stdlib" and "stdlib/" are considered // different paths in a zip file, but we want to abstract over that difference here // so that paths relative to the `VendoredFileSystem` // work the same as other paths in Ruff. - let mut archive = inner_locked.borrow_mut(); if let Ok(zip_file) = archive.lookup_path(&normalized) { return Some(Metadata::from_zip_file(zip_file)); } @@ -71,46 +69,45 @@ impl VendoredFileSystem { /// - The path exists in the underlying zip archive, but represents a directory /// - The contents of the zip file at `path` contain invalid UTF-8 pub fn read(&self, path: &VendoredPath) -> Result { - let inner_locked = self.inner.lock(); - let mut archive = inner_locked.borrow_mut(); + let mut archive = self.lock_archive(); let mut zip_file = archive.lookup_path(&NormalizedVendoredPath::from(path))?; let mut buffer = String::new(); zip_file.read_to_string(&mut buffer)?; Ok(buffer) } + + /// Acquire a lock on the underlying zip archive. + /// The call will block until it is able to acquire the lock. + /// + /// ## Panics: + /// If the current thread already holds the lock. + fn lock_archive(&self) -> LockedZipArchive { + self.inner.lock().unwrap() + } } impl fmt::Debug for VendoredFileSystem { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let locked_inner = self.inner.lock(); + let mut archive = self.lock_archive(); if f.alternate() { - let mut paths: Vec = locked_inner - .borrow() - .0 - .file_names() - .map(String::from) - .collect(); + let mut paths: Vec = archive.0.file_names().map(String::from).collect(); paths.sort(); let debug_info: BTreeMap = paths .iter() .map(|path| { ( path.to_owned(), - ZipFileDebugInfo::from(locked_inner.borrow_mut().0.by_name(path).unwrap()), + ZipFileDebugInfo::from(archive.0.by_name(path).unwrap()), ) }) .collect(); f.debug_struct("VendoredFileSystem") - .field("inner_mutex_poisoned", &self.inner.0.is_poisoned()) + .field("inner_mutex_poisoned", &self.inner.is_poisoned()) .field("paths", &paths) .field("data_by_path", &debug_info) .finish() } else { - write!( - f, - "VendoredFileSystem(<{} paths>)", - locked_inner.borrow().len() - ) + write!(f, "VendoredFileSystem(<{} paths>)", archive.len()) } } } @@ -196,27 +193,6 @@ impl Metadata { } } -struct VendoredFileSystemInner(Mutex>); - -type LockedZipArchive<'a> = MutexGuard<'a, RefCell>; - -impl VendoredFileSystemInner { - fn new(raw_bytes: &'static [u8]) -> Result { - Ok(Self(Mutex::new(RefCell::new(VendoredZipArchive::new( - raw_bytes, - )?)))) - } - - /// Acquire a lock on the underlying zip archive. - /// The call will block until it is able to acquire the lock. - /// - /// ## Panics: - /// If the current thread already holds the lock. - fn lock(&self) -> LockedZipArchive { - self.0.lock().unwrap() - } -} - /// Newtype wrapper around a ZipArchive. #[derive(Debug)] struct VendoredZipArchive(ZipArchive>);