From 6568d0c8c3559a2560606d6eee8e6528555bb82b Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 18 Mar 2022 15:27:01 +0100 Subject: [PATCH] Prevent race condition when watching model This temporarily leads to two initial loads of the model. I'm going to fix that in subsequent commits. --- fj-app/src/main.rs | 9 --------- fj-app/src/model.rs | 11 +++++++++++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/fj-app/src/main.rs b/fj-app/src/main.rs index ccb063e5b..9e68ab570 100644 --- a/fj-app/src/main.rs +++ b/fj-app/src/main.rs @@ -80,15 +80,6 @@ fn main() -> anyhow::Result<()> { parameters.insert(key, value); } - // Since we're loading the model before setting up the watcher below, - // there's a race condition, and a modification could be missed between - // those two events. - // - // This can't be addressed with the current structure, since the watcher - // closure takes ownership of the model. - // - // This is being tracked in the following issue: - // https://github.com/hannobraun/fornjot/issues/32 let shape = model.load(¶meters)?; let shape_processor = ShapeProcessor::new(args.tolerance)?; diff --git a/fj-app/src/model.rs b/fj-app/src/model.rs index 6020ffb3f..2febf8981 100644 --- a/fj-app/src/model.rs +++ b/fj-app/src/model.rs @@ -5,6 +5,7 @@ use std::{ path::PathBuf, process::Command, sync::mpsc, + thread, }; use notify::Watcher as _; @@ -100,6 +101,8 @@ impl Model { parameters: HashMap, ) -> Result { let (tx, rx) = mpsc::sync_channel(0); + let tx2 = tx.clone(); + let watch_path = self.src_path.clone(); let mut watcher = notify::recommended_watcher( @@ -155,6 +158,14 @@ impl Model { watcher.watch(&watch_path, notify::RecursiveMode::Recursive)?; + // To prevent a race condition between the initial load and the start of + // watching, we'll trigger the initial load here, after having started + // watching. + // + // Will panic, if the receiving end has panicked. Not much we can do + // about that, if it happened. + thread::spawn(move || tx2.send(()).unwrap()); + Ok(Watcher { _watcher: Box::new(watcher), channel: rx,