about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-06-08 12:36:18 +0200
committerGitHub <noreply@github.com>2023-06-08 12:36:18 +0200
commit4f2e1df29dd1090c666d9402f75d3ad5c804591c (patch)
tree375660f75ee6ecb9b77cc70f9b4373e8f6fae568
parent8747c0ebea5dd04311cb56310a5b2f0d32258d2f (diff)
parentfd3d2d49f2527efd2decad3a6194b82e26137bd8 (diff)
downloadrust-4f2e1df29dd1090c666d9402f75d3ad5c804591c.tar.gz
rust-4f2e1df29dd1090c666d9402f75d3ad5c804591c.zip
Rollup merge of #112333 - Zoxc:try_collect_active_jobs-deadlock, r=cjgillot
Don't hold the active queries lock while calling `make_query`

This moves the call to `make_query` outside the parts that holds the active queries lock in `try_collect_active_jobs`. This should help removed the deadlock and borrow panic that has been observed when printing the query stack during an ICE.

cc `@SparrowLii`
r? `@cjgillot`
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs15
1 files changed, 11 insertions, 4 deletions
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 730e4c8d30d..b2bc33c7e0d 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -69,6 +69,8 @@ where
         make_query: fn(Qcx, K) -> QueryStackFrame<D>,
         jobs: &mut QueryMap<D>,
     ) -> Option<()> {
+        let mut active = Vec::new();
+
         #[cfg(parallel_compiler)]
         {
             // We use try_lock_shards here since we are called from the
@@ -77,8 +79,7 @@ where
             for shard in shards.iter() {
                 for (k, v) in shard.iter() {
                     if let QueryResult::Started(ref job) = *v {
-                        let query = make_query(qcx, *k);
-                        jobs.insert(job.id, QueryJobInfo { query, job: job.clone() });
+                        active.push((*k, job.clone()));
                     }
                 }
             }
@@ -91,12 +92,18 @@ where
             // really hurt much.)
             for (k, v) in self.active.try_lock()?.iter() {
                 if let QueryResult::Started(ref job) = *v {
-                    let query = make_query(qcx, *k);
-                    jobs.insert(job.id, QueryJobInfo { query, job: job.clone() });
+                    active.push((*k, job.clone()));
                 }
             }
         }
 
+        // Call `make_query` while we're not holding a `self.active` lock as `make_query` may call
+        // queries leading to a deadlock.
+        for (key, job) in active {
+            let query = make_query(qcx, key);
+            jobs.insert(job.id, QueryJobInfo { query, job });
+        }
+
         Some(())
     }
 }