@@ -366,7 +366,10 @@ public bool LocalFindAndPop(object obj)
366366 else
367367 {
368368 // Failed, restore head.
369- m_headIndex = head ;
369+ // This write must complete before we return with a missed steal and check if
370+ // there is a pending thread request because the thread that responds
371+ // to the request must see the write to not conclude that the queue is empty.
372+ Interlocked . Exchange ( ref m_headIndex , head ) ;
370373 }
371374 }
372375 }
@@ -839,14 +842,17 @@ public long GlobalCount
839842 // Dispatch (if YieldFromDispatchLoop is true), or performing periodic activities
840843 public const uint DispatchQuantumMs = 30 ;
841844
845+ public enum DispatchResult
846+ {
847+ Spurious = 0 , // the thread was invited, but there was no work in the queue.
848+ Regular = 1 , // this thread did as much work as was available or its quantum expired.
849+ ShouldStop = 2 , // this thread stopped working early.
850+ }
851+
842852 /// <summary>
843853 /// Dispatches work items to this thread.
844854 /// </summary>
845- /// <returns>
846- /// <c>true</c> if this thread did as much work as was available or its quantum expired.
847- /// <c>false</c> if this thread stopped working early.
848- /// </returns>
849- internal static bool Dispatch ( )
855+ internal static DispatchResult Dispatch ( )
850856 {
851857 ThreadPoolWorkQueue workQueue = ThreadPool . s_workQueue ;
852858 ThreadPoolWorkQueueThreadLocals tl = workQueue . GetOrCreateThreadLocals ( ) ;
@@ -862,10 +868,11 @@ internal static bool Dispatch()
862868 ThreadPool . EnsureWorkerRequested ( ) ;
863869 }
864870
865- // Tell the VM we're returning normally, not because Hill Climbing asked us to return .
866- return true ;
871+ // The thread found no work .
872+ return DispatchResult . Spurious ;
867873 }
868874
875+
869876 // The workitems that are currently in the queues could have asked only for one worker.
870877 // We are going to process a workitem, which may take unknown time or even block.
871878 // In a worst case the current workitem will indirectly depend on progress of other
@@ -921,7 +928,7 @@ internal static bool Dispatch()
921928 ThreadPool . EnsureWorkerRequested ( ) ;
922929 }
923930
924- return true ;
931+ return DispatchResult . Regular ;
925932 }
926933 }
927934
@@ -977,7 +984,8 @@ internal static bool Dispatch()
977984 {
978985 workQueue . UnassignWorkItemQueue ( tl ) ;
979986 }
980- return false ;
987+
988+ return DispatchResult . ShouldStop ;
981989 }
982990
983991 // Check if the dispatch quantum has expired
@@ -997,7 +1005,7 @@ internal static bool Dispatch()
9971005 {
9981006 workQueue . UnassignWorkItemQueue ( tl ) ;
9991007 }
1000- return true ;
1008+ return DispatchResult . Regular ;
10011009 }
10021010
10031011 if ( s_assignableWorkItemQueueCount > 0 )
0 commit comments