From cf6ce9fd53dae24ec46142e2c9b249cb4ae102b1 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Thu, 14 Dec 2023 22:53:26 +0100 Subject: Make `World` thread-safe --- crates/typst-cli/src/fonts.rs | 8 ++++---- crates/typst-cli/src/world.rs | 28 +++++++++++++++------------- 2 files changed, 19 insertions(+), 17 deletions(-) (limited to 'crates/typst-cli') diff --git a/crates/typst-cli/src/fonts.rs b/crates/typst-cli/src/fonts.rs index f4711b82..7793840c 100644 --- a/crates/typst-cli/src/fonts.rs +++ b/crates/typst-cli/src/fonts.rs @@ -1,6 +1,6 @@ -use std::cell::OnceCell; use std::fs; use std::path::PathBuf; +use std::sync::OnceLock; use fontdb::{Database, Source}; use typst::diag::StrResult; @@ -42,7 +42,7 @@ pub struct FontSlot { /// to a collection. index: u32, /// The lazily loaded font. - font: OnceCell>, + font: OnceLock>, } impl FontSlot { @@ -92,7 +92,7 @@ impl FontSearcher { self.fonts.push(FontSlot { path: path.clone(), index: face.index, - font: OnceCell::new(), + font: OnceLock::new(), }); } } @@ -112,7 +112,7 @@ impl FontSearcher { self.fonts.push(FontSlot { path: PathBuf::new(), index: i as u32, - font: OnceCell::from(Some(font)), + font: OnceLock::from(Some(font)), }); } }; diff --git a/crates/typst-cli/src/world.rs b/crates/typst-cli/src/world.rs index 32a495e2..8f8a7e5c 100644 --- a/crates/typst-cli/src/world.rs +++ b/crates/typst-cli/src/world.rs @@ -1,6 +1,6 @@ -use std::cell::{OnceCell, RefCell, RefMut}; use std::collections::HashMap; use std::path::{Path, PathBuf}; +use std::sync::{OnceLock, RwLock}; use std::{fs, mem}; use chrono::{DateTime, Datelike, Local}; @@ -34,10 +34,10 @@ pub struct SystemWorld { /// Locations of and storage for lazily loaded fonts. fonts: Vec, /// Maps file ids to source files and buffers. - slots: RefCell>, + slots: RwLock>, /// The current datetime if requested. This is stored here to ensure it is /// always the same within one compilation. Reset between compilations. - now: OnceCell>, + now: OnceLock>, /// The export cache, used for caching output files in `typst watch` /// sessions. export_cache: ExportCache, @@ -78,8 +78,8 @@ impl SystemWorld { library: Prehashed::new(Library::build()), book: Prehashed::new(searcher.book), fonts: searcher.fonts, - slots: RefCell::default(), - now: OnceCell::new(), + slots: RwLock::new(HashMap::new()), + now: OnceLock::new(), export_cache: ExportCache::new(), }) } @@ -103,6 +103,7 @@ impl SystemWorld { pub fn dependencies(&mut self) -> impl Iterator + '_ { self.slots .get_mut() + .unwrap() .values() .filter(|slot| slot.accessed()) .filter_map(|slot| system_path(&self.root, slot.id).ok()) @@ -110,7 +111,7 @@ impl SystemWorld { /// Reset the compilation state in preparation of a new compilation. pub fn reset(&mut self) { - for slot in self.slots.get_mut().values_mut() { + for slot in self.slots.get_mut().unwrap().values_mut() { slot.reset(); } self.now.take(); @@ -147,11 +148,11 @@ impl World for SystemWorld { } fn source(&self, id: FileId) -> FileResult { - self.slot(id)?.source(&self.root) + self.slot(id, |slot| slot.source(&self.root)) } fn file(&self, id: FileId) -> FileResult { - self.slot(id)?.file(&self.root) + self.slot(id, |slot| slot.file(&self.root)) } fn font(&self, index: usize) -> Option { @@ -176,11 +177,12 @@ impl World for SystemWorld { impl SystemWorld { /// Access the canonical slot for the given file id. - #[tracing::instrument(skip_all)] - fn slot(&self, id: FileId) -> FileResult> { - Ok(RefMut::map(self.slots.borrow_mut(), |slots| { - slots.entry(id).or_insert_with(|| FileSlot::new(id)) - })) + fn slot(&self, id: FileId, f: F) -> T + where + F: FnOnce(&mut FileSlot) -> T, + { + let mut map = self.slots.write().unwrap(); + f(map.entry(id).or_insert_with(|| FileSlot::new(id))) } } -- cgit v1.2.3