@@ -94,15 +94,15 @@ impl<'tcx> QueryJob<'tcx> {
9494 #[ cfg( parallel_queries) ]
9595 {
9696 tls:: with_related_context ( tcx, move |icx| {
97- let mut waiter = QueryWaiter {
98- query : & icx. query ,
97+ let mut waiter = Lrc :: new ( QueryWaiter {
98+ query : icx. query . clone ( ) ,
9999 span,
100- cycle : None ,
100+ cycle : Lock :: new ( None ) ,
101101 condvar : Condvar :: new ( ) ,
102- } ;
103- self . latch . await ( & mut waiter) ;
102+ } ) ;
103+ self . latch . await ( & waiter) ;
104104
105- match waiter. cycle {
105+ match Lrc :: get_mut ( & mut waiter) . unwrap ( ) . cycle . get_mut ( ) . take ( ) {
106106 None => Ok ( ( ) ) ,
107107 Some ( cycle) => Err ( cycle)
108108 }
@@ -154,10 +154,10 @@ impl<'tcx> QueryJob<'tcx> {
154154
155155#[ cfg( parallel_queries) ]
156156struct QueryWaiter < ' tcx > {
157- query : * const Option < Lrc < QueryJob < ' tcx > > > ,
157+ query : Option < Lrc < QueryJob < ' tcx > > > ,
158158 condvar : Condvar ,
159159 span : Span ,
160- cycle : Option < CycleError < ' tcx > > ,
160+ cycle : Lock < Option < CycleError < ' tcx > > > ,
161161}
162162
163163#[ cfg( parallel_queries) ]
@@ -171,13 +171,9 @@ impl<'tcx> QueryWaiter<'tcx> {
171171#[ cfg( parallel_queries) ]
172172struct QueryLatchInfo < ' tcx > {
173173 complete : bool ,
174- waiters : Vec < * mut QueryWaiter < ' tcx > > ,
174+ waiters : Vec < Lrc < QueryWaiter < ' tcx > > > ,
175175}
176176
177- // Required because of raw pointers
178- #[ cfg( parallel_queries) ]
179- unsafe impl < ' tcx > Send for QueryLatchInfo < ' tcx > { }
180-
181177#[ cfg( parallel_queries) ]
182178struct QueryLatch < ' tcx > {
183179 info : Mutex < QueryLatchInfo < ' tcx > > ,
@@ -195,14 +191,14 @@ impl<'tcx> QueryLatch<'tcx> {
195191 }
196192
197193 /// Awaits the caller on this latch by blocking the current thread.
198- fn await ( & self , waiter : & mut QueryWaiter < ' tcx > ) {
194+ fn await ( & self , waiter : & Lrc < QueryWaiter < ' tcx > > ) {
199195 let mut info = self . info . lock ( ) ;
200196 if !info. complete {
201197 // We push the waiter on to the `waiters` list. It can be accessed inside
202198 // the `wait` call below, by 1) the `set` method or 2) by deadlock detection.
203199 // Both of these will remove it from the `waiters` list before resuming
204200 // this thread.
205- info. waiters . push ( waiter) ;
201+ info. waiters . push ( waiter. clone ( ) ) ;
206202
207203 // If this detects a deadlock and the deadlock handler want to resume this thread
208204 // we have to be in the `wait` call. This is ensured by the deadlock handler
@@ -219,9 +215,7 @@ impl<'tcx> QueryLatch<'tcx> {
219215 info. complete = true ;
220216 let registry = rayon_core:: Registry :: current ( ) ;
221217 for waiter in info. waiters . drain ( ..) {
222- unsafe {
223- ( * waiter) . notify ( & registry) ;
224- }
218+ waiter. notify ( & registry) ;
225219 }
226220 }
227221
@@ -230,7 +224,7 @@ impl<'tcx> QueryLatch<'tcx> {
230224 fn extract_waiter (
231225 & self ,
232226 waiter : usize ,
233- ) -> * mut QueryWaiter < ' tcx > {
227+ ) -> Lrc < QueryWaiter < ' tcx > > {
234228 let mut info = self . info . lock ( ) ;
235229 debug_assert ! ( !info. complete) ;
236230 // Remove the waiter from the list of waiters
@@ -270,13 +264,11 @@ where
270264 }
271265
272266 // Visit the explict waiters which use condvars and are resumable
273- for ( i, & waiter) in query. latch . info . lock ( ) . waiters . iter ( ) . enumerate ( ) {
274- unsafe {
275- if let Some ( ref waiter_query) = * ( * waiter) . query {
276- if visit ( ( * waiter) . span , & * * waiter_query as Ref ) . is_some ( ) {
277- // Return a value which indicates that this waiter can be resumed
278- return Some ( Some ( ( query_ref, i) ) ) ;
279- }
267+ for ( i, waiter) in query. latch . info . lock ( ) . waiters . iter ( ) . enumerate ( ) {
268+ if let Some ( ref waiter_query) = waiter. query {
269+ if visit ( waiter. span , & * * waiter_query) . is_some ( ) {
270+ // Return a value which indicates that this waiter can be resumed
271+ return Some ( Some ( ( query_ref, i) ) ) ;
280272 }
281273 }
282274 }
@@ -359,7 +351,7 @@ fn connected_to_root<'tcx>(query: Ref<'tcx>, visited: &mut HashSet<Ref<'tcx>>) -
359351#[ cfg( parallel_queries) ]
360352fn remove_cycle < ' tcx > (
361353 jobs : & mut Vec < Ref < ' tcx > > ,
362- wakelist : & mut Vec < * mut QueryWaiter < ' tcx > > ,
354+ wakelist : & mut Vec < Lrc < QueryWaiter < ' tcx > > > ,
363355 tcx : TyCtxt < ' _ , ' tcx , ' _ >
364356) -> bool {
365357 let mut visited = HashSet :: new ( ) ;
@@ -439,9 +431,9 @@ fn remove_cycle<'tcx>(
439431 // Extract the waiter we want to resume
440432 let waiter = waitee_query. latch . extract_waiter ( waiter_idx) ;
441433
442- // Set the cycle error it will be picked it up when resumed
434+ // Set the cycle error so it will be picked up when resumed
443435 unsafe {
444- ( * waiter) . cycle = Some ( error) ;
436+ * waiter. cycle . lock ( ) = Some ( error) ;
445437 }
446438
447439 // Put the waiter on the list of things to resume
@@ -525,9 +517,7 @@ fn deadlock(tcx: TyCtxt<'_, '_, '_>, registry: &rayon_core::Registry) {
525517
526518 // FIXME: Ensure this won't cause a deadlock before we return
527519 for waiter in wakelist. into_iter ( ) {
528- unsafe {
529- ( * waiter) . notify ( registry) ;
530- }
520+ waiter. notify ( registry) ;
531521 }
532522
533523 on_panic. disable ( ) ;
0 commit comments