@@ -373,10 +373,10 @@ internal open class JobSupport constructor(active: Boolean) : Job, SelectClause0
373
373
onStartInternal()
374
374
return TRUE
375
375
}
376
- is NodeList -> { // LIST -- a list of completion handlers (either new or active)
377
- return state.tryMakeActive(). also { result ->
378
- if (result == TRUE ) onStartInternal()
379
- }
376
+ is InactiveNodeList -> { // LIST state -- inactive with a list of completion handlers
377
+ if ( ! _state .compareAndSet(state, state.list)) return RETRY
378
+ onStartInternal()
379
+ return TRUE
380
380
}
381
381
else -> return FALSE // not a new state
382
382
}
@@ -486,13 +486,15 @@ internal open class JobSupport constructor(active: Boolean) : Job, SelectClause0
486
486
list.addLastIf(node) { this .state == = expect }
487
487
488
488
private fun promoteEmptyToNodeList (state : Empty ) {
489
- // try to promote it to list in new state
490
- _state .compareAndSet(state, NodeList (state.isActive))
489
+ // try to promote it to LIST state with the corresponding state
490
+ val list = NodeList ()
491
+ val update = if (state.isActive) list else InactiveNodeList (list)
492
+ _state .compareAndSet(state, update)
491
493
}
492
494
493
495
private fun promoteSingleToNodeList (state : JobNode <* >) {
494
496
// try to promote it to list (SINGLE+ state)
495
- state.addOneIfEmpty(NodeList (active = true ))
497
+ state.addOneIfEmpty(NodeList ())
496
498
// it must be in SINGLE+ state or state has changed (node could have need removed from state)
497
499
val list = state.nextNode // either our NodeList or somebody else won the race, updated state
498
500
// just attempt converting it to list if state is still the same, then we'll continue lock-free loop
@@ -597,14 +599,13 @@ internal open class JobSupport constructor(active: Boolean) : Job, SelectClause0
597
599
is JobNode <* > -> { // SINGLE/SINGLE+ state -- one completion handler
598
600
promoteSingleToNodeList(state)
599
601
}
600
- is NodeList -> { // LIST -- a list of completion handlers (either new or active)
601
- if (state.isActive) {
602
- if (tryMakeCancelling(state, state.list, cause)) return true
603
- } else {
604
- // cancelling a non-started coroutine makes it immediately cancelled
605
- if (updateStateCancelled(state, cause))
606
- return true
607
- }
602
+ is NodeList -> { // LIST -- active list of completion handlers
603
+ if (tryMakeCancelling(state, state.list, cause)) return true
604
+ }
605
+ is InactiveNodeList -> { // LIST -- inactive list of completion handlers
606
+ // cancelling a non-started coroutine makes it immediately cancelled
607
+ if (updateStateCancelled(state, cause))
608
+ return true
608
609
}
609
610
is Finishing -> { // Completing/Cancelling the job, may cancel
610
611
if (state.cancelled != null ) {
@@ -1079,31 +1080,30 @@ internal abstract class JobNode<out J : Job>(
1079
1080
override fun dispose () = (job as JobSupport ).removeNode(this )
1080
1081
}
1081
1082
1082
- internal class NodeList (
1083
- active : Boolean
1084
- ) : LockFreeLinkedListHead(), Incomplete {
1085
- private val _active = atomic(if (active) 1 else 0 )
1086
-
1087
- override val isActive: Boolean get() = _active .value != 0
1083
+ internal class NodeList : LockFreeLinkedListHead (), Incomplete {
1084
+ override val isActive: Boolean get() = true
1088
1085
override val list: NodeList get() = this
1089
1086
1090
- fun tryMakeActive (): Int {
1091
- if (_active .value != 0 ) return FALSE
1092
- if (_active .compareAndSet(0 , 1 )) return TRUE
1093
- return RETRY
1094
- }
1095
-
1096
- override fun toString (): String = buildString {
1097
- append(" List" )
1098
- append(if (isActive) " {Active}" else " {New}" )
1099
- append(" [" )
1087
+ fun getString (state : String ) = buildString {
1088
+ append(" List{" )
1089
+ append(state)
1090
+ append(" }[" )
1100
1091
var first = true
1101
1092
this @NodeList.forEach<JobNode <* >> { node ->
1102
1093
if (first) first = false else append(" , " )
1103
1094
append(node)
1104
1095
}
1105
1096
append(" ]" )
1106
1097
}
1098
+
1099
+ override fun toString (): String = getString(" Active" )
1100
+ }
1101
+
1102
+ internal class InactiveNodeList (
1103
+ override val list : NodeList
1104
+ ) : Incomplete {
1105
+ override val isActive: Boolean get() = false
1106
+ override fun toString (): String = list.getString(" New" )
1107
1107
}
1108
1108
1109
1109
private class InvokeOnCompletion (
0 commit comments