@@ -640,6 +640,7 @@ internal open class JobSupport constructor(active: Boolean) : Job, SelectClause0
640
640
private fun tryMakeCancelling (expect : Incomplete , list : NodeList , cause : Throwable ? ): Boolean {
641
641
val cancelled = Cancelled (this , cause)
642
642
if (! _state .compareAndSet(expect, Finishing (list, cancelled, false ))) return false
643
+ onFinishingInternal(cancelled)
643
644
onCancellationInternal(cancelled)
644
645
// Materialize cause
645
646
notifyCancellation(list, cancelled.cause)
@@ -678,10 +679,10 @@ internal open class JobSupport constructor(active: Boolean) : Job, SelectClause0
678
679
if (state is Finishing && state.completing)
679
680
return COMPLETING_ALREADY_COMPLETING
680
681
val child: ChildJob ? = firstChild(state) ? : // or else complete immediately w/o children
681
- if (tryFinalizeState(state, proposedUpdate, mode)) {
682
- return COMPLETING_COMPLETED
683
- } else {
684
- return @loopOnState // retry
682
+ when {
683
+ state !is Finishing && hasOnFinishingHandler(proposedUpdate) -> null // unless it has onFinishing handler
684
+ tryFinalizeState(state, proposedUpdate, mode) -> return COMPLETING_COMPLETED
685
+ else -> return @loopOnState
685
686
}
686
687
val list = state.list ? : // must promote to list to correctly operate on child lists
687
688
when (state) {
@@ -703,6 +704,7 @@ internal open class JobSupport constructor(active: Boolean) : Job, SelectClause0
703
704
val completing = Finishing (list, cancelled, true )
704
705
if (_state .compareAndSet(state, completing)) {
705
706
(state as ? Finishing )?.transferExceptions(completing)
707
+ if (state !is Finishing ) onFinishingInternal(proposedUpdate)
706
708
if (child != null && tryWaitForChild(child, proposedUpdate))
707
709
return COMPLETING_WAITING_CHILDREN
708
710
if (tryFinalizeState(completing, proposedUpdate, mode = MODE_ATOMIC_DEFAULT ))
@@ -798,6 +800,17 @@ internal open class JobSupport constructor(active: Boolean) : Job, SelectClause0
798
800
// TODO rename to "onCancelling"
799
801
}
800
802
803
+ /* *
804
+ * Whether job has [onFinishingInternal] handler for given [update]
805
+ * @suppress **This is unstable API and it is subject to change.**
806
+ */
807
+ internal open fun hasOnFinishingHandler (update : Any? ) = false
808
+
809
+ /* *
810
+ * @suppress **This is unstable API and it is subject to change.**
811
+ */
812
+ internal open fun onFinishingInternal (update : Any? ) {}
813
+
801
814
/* *
802
815
* Method which is invoked once Job becomes [Cancelled] or [CompletedExceptionally].
803
816
* It's guaranteed that at the moment of invocation the job and all its children are complete.
0 commit comments