Skip to content

Commit 67912f9

Browse files
committed
Revert "Removed legacy onFinishing handler support from JobSupport"
This reverts commit b209e9b
1 parent b209e9b commit 67912f9

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

common/kotlinx-coroutines-core-common/src/Builders.common.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,17 @@ private open class StandaloneCoroutine(
210210
private val parentContext: CoroutineContext,
211211
active: Boolean
212212
) : AbstractCoroutine<Unit>(parentContext, active) {
213+
override fun hasOnFinishingHandler(update: Any?) = update is CompletedExceptionally
214+
213215
override fun handleJobException(exception: Throwable) {
214216
handleCoroutineException(parentContext, exception, this)
215217
}
218+
219+
override fun onFinishingInternal(update: Any?) {
220+
if (update is CompletedExceptionally && update.cause !is CancellationException) {
221+
parentContext[Job]?.cancel(update.cause)
222+
}
223+
}
216224
}
217225

218226
private class LazyStandaloneCoroutine(

common/kotlinx-coroutines-core-common/src/JobSupport.kt

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,7 @@ internal open class JobSupport constructor(active: Boolean) : Job, SelectClause0
640640
private fun tryMakeCancelling(expect: Incomplete, list: NodeList, cause: Throwable?): Boolean {
641641
val cancelled = Cancelled(this, cause)
642642
if (!_state.compareAndSet(expect, Finishing(list, cancelled, false))) return false
643+
onFinishingInternal(cancelled)
643644
onCancellationInternal(cancelled)
644645
// Materialize cause
645646
notifyCancellation(list, cancelled.cause)
@@ -678,10 +679,10 @@ internal open class JobSupport constructor(active: Boolean) : Job, SelectClause0
678679
if (state is Finishing && state.completing)
679680
return COMPLETING_ALREADY_COMPLETING
680681
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
685686
}
686687
val list = state.list ?: // must promote to list to correctly operate on child lists
687688
when (state) {
@@ -703,6 +704,7 @@ internal open class JobSupport constructor(active: Boolean) : Job, SelectClause0
703704
val completing = Finishing(list, cancelled, true)
704705
if (_state.compareAndSet(state, completing)) {
705706
(state as? Finishing)?.transferExceptions(completing)
707+
if (state !is Finishing) onFinishingInternal(proposedUpdate)
706708
if (child != null && tryWaitForChild(child, proposedUpdate))
707709
return COMPLETING_WAITING_CHILDREN
708710
if (tryFinalizeState(completing, proposedUpdate, mode = MODE_ATOMIC_DEFAULT))
@@ -798,6 +800,17 @@ internal open class JobSupport constructor(active: Boolean) : Job, SelectClause0
798800
// TODO rename to "onCancelling"
799801
}
800802

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+
801814
/**
802815
* Method which is invoked once Job becomes [Cancelled] or [CompletedExceptionally].
803816
* It's guaranteed that at the moment of invocation the job and all its children are complete.

0 commit comments

Comments
 (0)