@@ -111,21 +111,19 @@ internal class CoroutineScheduler(
111
111
*
112
112
* Note, [newIndex] can be zero for the worker that is being terminated (removed from [workers]).
113
113
*/
114
- private fun parkedWorkersStackTopUpdate (oldIndex : Int , newIndex : Int ) {
114
+ private fun parkedWorkersStackTopUpdate (worker : Worker , oldIndex : Int , newIndex : Int ) {
115
115
parkedWorkersStack.loop { top ->
116
116
val index = (top and PARKED_INDEX_MASK ).toInt()
117
117
val updVersion = (top + PARKED_VERSION_INC ) and PARKED_VERSION_MASK
118
118
val updIndex = if (index == oldIndex) {
119
119
if (newIndex == 0 ) {
120
- parkedWorkersStackNextIndex(workers[oldIndex]!! )
121
- }
122
- else {
120
+ parkedWorkersStackNextIndex(worker)
121
+ } else {
123
122
newIndex
124
123
}
125
124
} else {
126
125
index // no change to index, but update version
127
126
}
128
-
129
127
if (updIndex < 0 ) return @loop // retry
130
128
if (parkedWorkersStack.compareAndSet(top, updVersion or updIndex.toLong())) return
131
129
}
@@ -254,7 +252,7 @@ internal class CoroutineScheduler(
254
252
private const val MAX_SPINS = 1000
255
253
private const val MAX_YIELDS = MAX_SPINS + 500
256
254
257
- @JvmStatic // Note, that is fits into Int (it is is equal to 10^9)
255
+ @JvmStatic // Note, that is fits into Int (it is equal to 10^9)
258
256
private val MAX_PARK_TIME_NS = TimeUnit .SECONDS .toNanos(1 ).toInt()
259
257
260
258
@JvmStatic
@@ -824,10 +822,7 @@ internal class CoroutineScheduler(
824
822
* See tryUnpark for state reasoning.
825
823
* If this CAS fails, then we were successfully unparked by other worker and cannot terminate.
826
824
*/
827
- if (! terminationState.compareAndSet(
828
- ALLOWED ,
829
- TERMINATED
830
- )) return
825
+ if (! terminationState.compareAndSet(ALLOWED , TERMINATED )) return
831
826
/*
832
827
* At this point this thread is no longer considered as usable for scheduling.
833
828
* We need multi-step choreography to reindex workers.
@@ -843,22 +838,25 @@ internal class CoroutineScheduler(
843
838
* 2) Update top of stack if it was pointing to oldIndex and make sure no
844
839
* pending push/pop operation that might have already retrieved oldIndex could complete.
845
840
*/
846
- parkedWorkersStackTopUpdate(oldIndex, 0 )
841
+ parkedWorkersStackTopUpdate(this , oldIndex, 0 )
847
842
/*
848
- * 3) Move last worker into an index in array that was previously occupied by this worker.
843
+ * 3) Move last worker into an index in array that was previously occupied by this worker,
844
+ * if last worker was a different one (sic!).
849
845
*/
850
846
val lastIndex = decrementCreatedWorkers()
851
- val lastWorker = workers[lastIndex]!!
852
- workers[oldIndex] = lastWorker
853
- lastWorker.indexInArray = oldIndex
854
- /*
855
- * Now lastWorker is available at both indices in the array, but it can
856
- * still be at the stack top on via its lastIndex
857
- *
858
- * 4) Update top of stack lastIndex -> oldIndex and make sure no
859
- * pending push/pop operation that might have already retrieved lastIndex could complete.
860
- */
861
- parkedWorkersStackTopUpdate(lastIndex, oldIndex)
847
+ if (lastIndex != oldIndex) {
848
+ val lastWorker = workers[lastIndex]!!
849
+ workers[oldIndex] = lastWorker
850
+ lastWorker.indexInArray = oldIndex
851
+ /*
852
+ * Now lastWorker is available at both indices in the array, but it can
853
+ * still be at the stack top on via its lastIndex
854
+ *
855
+ * 4) Update top of stack lastIndex -> oldIndex and make sure no
856
+ * pending push/pop operation that might have already retrieved lastIndex could complete.
857
+ */
858
+ parkedWorkersStackTopUpdate(lastWorker, lastIndex, oldIndex)
859
+ }
862
860
/*
863
861
* 5) It is safe to clear reference from workers array now.
864
862
*/
0 commit comments