@@ -813,23 +813,33 @@ impl WorkerThread {
813
813
// accesses, which would be *very bad*
814
814
let abort_guard = unwind:: AbortIfPanic ;
815
815
816
- let mut idle_state = self . registry . sleep . start_looking ( self . index , latch ) ;
817
- while !latch . probe ( ) {
818
- if let Some ( job ) = self . find_work ( ) {
819
- self . registry . sleep . work_found ( idle_state ) ;
816
+ ' outer : while !latch . probe ( ) {
817
+ // Check for local work *before* we start marking ourself idle,
818
+ // especially to avoid modifying shared sleep state.
819
+ if let Some ( job ) = self . take_local_job ( ) {
820
820
self . execute ( job) ;
821
- idle_state = self . registry . sleep . start_looking ( self . index , latch) ;
822
- } else {
823
- self . registry
824
- . sleep
825
- . no_work_found ( & mut idle_state, latch, || self . has_injected_job ( ) )
821
+ continue ;
826
822
}
827
- }
828
823
829
- // If we were sleepy, we are not anymore. We "found work" --
830
- // whatever the surrounding thread was doing before it had to
831
- // wait.
832
- self . registry . sleep . work_found ( idle_state) ;
824
+ let mut idle_state = self . registry . sleep . start_looking ( self . index , latch) ;
825
+ while !latch. probe ( ) {
826
+ if let Some ( job) = self . find_work ( ) {
827
+ self . registry . sleep . work_found ( idle_state) ;
828
+ self . execute ( job) ;
829
+ // The job might have injected local work, so go back to the outer loop.
830
+ continue ' outer;
831
+ } else {
832
+ self . registry
833
+ . sleep
834
+ . no_work_found ( & mut idle_state, latch, || self . has_injected_job ( ) )
835
+ }
836
+ }
837
+
838
+ // If we were sleepy, we are not anymore. We "found work" --
839
+ // whatever the surrounding thread was doing before it had to wait.
840
+ self . registry . sleep . work_found ( idle_state) ;
841
+ break ;
842
+ }
833
843
834
844
self . log ( || ThreadSawLatchSet {
835
845
worker : self . index ,
0 commit comments