@@ -122,10 +122,10 @@ internal open class CancellableContinuationImpl<in T>(
122
122
val completed = isCompleted
123
123
if (resumeMode != MODE_ATOMIC_DEFAULT ) return completed // Do not check postponed cancellation for non-reusable continuations
124
124
val dispatched = delegate as ? DispatchedContinuation <* > ? : return completed
125
- val cancelled = dispatched.checkPostponedCancellation(this ) ? : return completed
125
+ val cause = dispatched.checkPostponedCancellation(this ) ? : return completed
126
126
if (! completed) {
127
127
// Note: this cancel may fail if one more concurrent cancel is currently being invoked
128
- cancel(cancelled. cause)
128
+ cancel(cause)
129
129
}
130
130
return true
131
131
}
@@ -148,21 +148,13 @@ internal open class CancellableContinuationImpl<in T>(
148
148
/*
149
149
* Attempt to postpone cancellation for reusable cancellable continuation
150
150
*/
151
- private fun cancelLater (cancelled : CancelledContinuation ): Boolean {
151
+ private fun cancelLater (cause : Throwable ): Boolean {
152
152
if (resumeMode != MODE_ATOMIC_DEFAULT ) return false
153
153
val dispatched = (delegate as ? DispatchedContinuation <* >) ? : return false
154
- return dispatched.postponeCancellation(cancelled )
154
+ return dispatched.postponeCancellation(cause )
155
155
}
156
156
157
157
public override fun cancel (cause : Throwable ? ): Boolean {
158
- if (cancelLater(CancelledContinuation (this , cause, handled = state is CancelHandler ))) {
159
- /*
160
- * Here we can't reliably say whether postponed cancellation will be successful, but as it's internal API
161
- * and we do not rely on return value, we are free to return `true`.
162
- */
163
- return true
164
- }
165
-
166
158
_state .loop { state ->
167
159
if (state !is NotCompleted ) return false // false if already complete or cancelling
168
160
// Active -- update to final state
@@ -171,12 +163,21 @@ internal open class CancellableContinuationImpl<in T>(
171
163
// Invoke cancel handler if it was present
172
164
if (state is CancelHandler ) invokeHandlerSafely { state.invoke(cause) }
173
165
// Complete state update
174
- disposeParentHandle ()
166
+ detachChildIfNonResuable ()
175
167
dispatchResume(mode = MODE_ATOMIC_DEFAULT )
176
168
return true
177
169
}
178
170
}
179
171
172
+ internal fun parentCancelled (cause : Throwable ) {
173
+ /*
174
+ * Here we can't reliably say whether postponed cancellation will be successful, but as it's internal API
175
+ * and we do not rely on return value, we are free to return `true`.
176
+ */
177
+ if (cancelLater(cause)) return
178
+ cancel(cause)
179
+ }
180
+
180
181
private inline fun invokeHandlerSafely (block : () -> Unit ) {
181
182
try {
182
183
block()
@@ -308,7 +309,7 @@ internal open class CancellableContinuationImpl<in T>(
308
309
when (state) {
309
310
is NotCompleted -> {
310
311
if (! _state .compareAndSet(state, proposedUpdate)) return @loop // retry on cas failure
311
- disposeParentHandle ()
312
+ detachChildIfNonResuable ()
312
313
dispatchResume(resumeMode)
313
314
return null
314
315
}
@@ -330,14 +331,9 @@ internal open class CancellableContinuationImpl<in T>(
330
331
}
331
332
332
333
// Unregister from parent job
333
- private fun disposeParentHandle () {
334
- // If instance is reusable, do not detach on every reuse, #releaseInterceptedContinuation
335
- // will do it for us in the end
336
- if (isReusable()) return
337
- parentHandle?.let { // volatile read parentHandle (once)
338
- it.dispose()
339
- parentHandle = NonDisposableHandle // release it just in case, to aid GC
340
- }
334
+ private fun detachChildIfNonResuable () {
335
+ // If instance is reusable, do not detach on every reuse, #releaseInterceptedContinuation will do it for us in the end
336
+ if (! isReusable()) detachChild()
341
337
}
342
338
343
339
/* *
@@ -361,7 +357,7 @@ internal open class CancellableContinuationImpl<in T>(
361
357
val update: Any? = if (idempotent == null ) value else
362
358
CompletedIdempotentResult (idempotent, value, state)
363
359
if (! _state .compareAndSet(state, update)) return @loop // retry on cas failure
364
- disposeParentHandle ()
360
+ detachChildIfNonResuable ()
365
361
return state
366
362
}
367
363
is CompletedIdempotentResult -> {
@@ -383,7 +379,7 @@ internal open class CancellableContinuationImpl<in T>(
383
379
is NotCompleted -> {
384
380
val update = CompletedExceptionally (exception)
385
381
if (! _state .compareAndSet(state, update)) return @loop // retry on cas failure
386
- disposeParentHandle ()
382
+ detachChildIfNonResuable ()
387
383
return state
388
384
}
389
385
else -> return null // cannot resume -- not active anymore
0 commit comments