From ce8c6c47626c3fee3ca49fb3aec4f2c588b3db7a Mon Sep 17 00:00:00 2001 From: Boris-Chengbiao Zhou Date: Thu, 29 Apr 2021 21:12:48 +0200 Subject: Ensure that only one cache priming task can run at a time Fixes #8632. --- crates/rust-analyzer/src/global_state.rs | 2 ++ crates/rust-analyzer/src/main_loop.rs | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) (limited to 'crates') diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index adeb7a97e..6f2f482c1 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -84,6 +84,7 @@ pub(crate) struct GlobalState { pub(crate) workspace_build_data: Option, pub(crate) fetch_build_data_queue: OpQueue>>, + pub(crate) prime_caches_queue: OpQueue<(), ()>, latest_requests: Arc>, } @@ -146,6 +147,7 @@ impl GlobalState { workspaces: Arc::new(Vec::new()), fetch_workspaces_queue: OpQueue::default(), workspace_build_data: None, + prime_caches_queue: OpQueue::default(), fetch_build_data_queue: OpQueue::default(), latest_requests: Default::default(), diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index a766aacad..a3e974e92 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -278,6 +278,8 @@ impl GlobalState { }; } + let mut finished = false; + for progress in prime_caches_progress { let (state, message, fraction); match progress { @@ -295,11 +297,18 @@ impl GlobalState { state = Progress::End; message = None; fraction = 1.0; + finished = true; } }; self.report_progress("Indexing", state, message, Some(fraction)); } + + // If the task is cancelled we may observe two `PrimeCachesProgress::Finished` so we + // have to make sure to only call `op_completed()` once. + if finished { + self.prime_caches_queue.op_completed(()); + } } Event::Vfs(mut task) => { let _p = profile::span("GlobalState::handle_event/vfs"); @@ -711,6 +720,13 @@ impl GlobalState { } fn update_file_notifications_on_threadpool(&mut self) { self.maybe_update_diagnostics(); + + // Ensure that only one cache priming task can run at a time + self.prime_caches_queue.request_op(()); + if self.prime_caches_queue.should_start_op().is_none() { + return; + } + self.task_pool.handle.spawn_with_sender({ let snap = self.snapshot(); move |sender| { -- cgit v1.2.3