69
69
make_query : fn ( Qcx , K ) -> QueryStackFrame < D > ,
70
70
jobs : & mut QueryMap < D > ,
71
71
) -> Option < ( ) > {
72
+ let mut active = Vec :: new ( ) ;
73
+
72
74
#[ cfg( parallel_compiler) ]
73
75
{
74
76
// We use try_lock_shards here since we are called from the
77
79
for shard in shards. iter ( ) {
78
80
for ( k, v) in shard. iter ( ) {
79
81
if let QueryResult :: Started ( ref job) = * v {
80
- let query = make_query ( qcx, * k) ;
81
- jobs. insert ( job. id , QueryJobInfo { query, job : job. clone ( ) } ) ;
82
+ active. push ( ( * k, job. clone ( ) ) ) ;
82
83
}
83
84
}
84
85
}
@@ -91,12 +92,18 @@ where
91
92
// really hurt much.)
92
93
for ( k, v) in self . active . try_lock ( ) ?. iter ( ) {
93
94
if let QueryResult :: Started ( ref job) = * v {
94
- let query = make_query ( qcx, * k) ;
95
- jobs. insert ( job. id , QueryJobInfo { query, job : job. clone ( ) } ) ;
95
+ active. push ( ( * k, job. clone ( ) ) ) ;
96
96
}
97
97
}
98
98
}
99
99
100
+ // Call `make_query` while we're not holding a `self.active` lock as `make_query` may call
101
+ // queries leading to a deadlock.
102
+ for ( key, job) in active {
103
+ let query = make_query ( qcx, key) ;
104
+ jobs. insert ( job. id , QueryJobInfo { query, job } ) ;
105
+ }
106
+
100
107
Some ( ( ) )
101
108
}
102
109
}
0 commit comments