Skip to content

Commit b9b8dc4

Browse files
committed
New select and Mutex algorithms
1 parent ec9be92 commit b9b8dc4

38 files changed

+1502
-1583
lines changed

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ junit5_version=5.7.0
1313
atomicfu_version=0.17.0
1414
knit_version=0.3.0
1515
html_version=0.7.2
16-
lincheck_version=2.14
16+
lincheck_version=2.14.1
1717
dokka_version=1.6.0-dev-138
1818
byte_buddy_version=1.10.9
1919
reactor_version=3.4.1

kotlinx-coroutines-core/api/kotlinx-coroutines-core.api

+74-40
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ public final class kotlinx/coroutines/JobKt {
410410
public static final fun isActive (Lkotlin/coroutines/CoroutineContext;)Z
411411
}
412412

413-
public class kotlinx/coroutines/JobSupport : kotlinx/coroutines/ChildJob, kotlinx/coroutines/Job, kotlinx/coroutines/ParentJob, kotlinx/coroutines/selects/SelectClause0 {
413+
public class kotlinx/coroutines/JobSupport : kotlinx/coroutines/ChildJob, kotlinx/coroutines/Job, kotlinx/coroutines/ParentJob {
414414
public fun <init> (Z)V
415415
protected fun afterCompletion (Ljava/lang/Object;)V
416416
public final fun attachChild (Lkotlinx/coroutines/ChildJob;)Lkotlinx/coroutines/ChildHandle;
@@ -448,7 +448,6 @@ public class kotlinx/coroutines/JobSupport : kotlinx/coroutines/ChildJob, kotlin
448448
public final fun parentCancelled (Lkotlinx/coroutines/ParentJob;)V
449449
public fun plus (Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext;
450450
public fun plus (Lkotlinx/coroutines/Job;)Lkotlinx/coroutines/Job;
451-
public final fun registerSelectClause0 (Lkotlinx/coroutines/selects/SelectInstance;Lkotlin/jvm/functions/Function1;)V
452451
public final fun start ()Z
453452
protected final fun toCancellationException (Ljava/lang/Throwable;Ljava/lang/String;)Ljava/util/concurrent/CancellationException;
454453
public static synthetic fun toCancellationException$default (Lkotlinx/coroutines/JobSupport;Ljava/lang/Throwable;Ljava/lang/String;ILjava/lang/Object;)Ljava/util/concurrent/CancellationException;
@@ -1178,83 +1177,118 @@ public class kotlinx/coroutines/scheduling/ExperimentalCoroutineDispatcher : kot
11781177
public fun toString ()Ljava/lang/String;
11791178
}
11801179

1180+
public final class kotlinx/coroutines/selects/OnTimeoutKt {
1181+
public static final fun onTimeout (Lkotlinx/coroutines/selects/SelectBuilder;JLkotlin/jvm/functions/Function1;)V
1182+
public static final fun onTimeout-8Mi8wO0 (Lkotlinx/coroutines/selects/SelectBuilder;JLkotlin/jvm/functions/Function1;)V
1183+
}
1184+
11811185
public abstract interface class kotlinx/coroutines/selects/SelectBuilder {
11821186
public abstract fun invoke (Lkotlinx/coroutines/selects/SelectClause0;Lkotlin/jvm/functions/Function1;)V
11831187
public abstract fun invoke (Lkotlinx/coroutines/selects/SelectClause1;Lkotlin/jvm/functions/Function2;)V
11841188
public abstract fun invoke (Lkotlinx/coroutines/selects/SelectClause2;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
11851189
public abstract fun invoke (Lkotlinx/coroutines/selects/SelectClause2;Lkotlin/jvm/functions/Function2;)V
1186-
public abstract fun onTimeout (JLkotlin/jvm/functions/Function1;)V
1190+
public abstract synthetic fun onTimeout (JLkotlin/jvm/functions/Function1;)V
11871191
}
11881192

11891193
public final class kotlinx/coroutines/selects/SelectBuilder$DefaultImpls {
11901194
public static fun invoke (Lkotlinx/coroutines/selects/SelectBuilder;Lkotlinx/coroutines/selects/SelectClause2;Lkotlin/jvm/functions/Function2;)V
1195+
public static synthetic fun onTimeout (Lkotlinx/coroutines/selects/SelectBuilder;JLkotlin/jvm/functions/Function1;)V
11911196
}
11921197

1193-
public final class kotlinx/coroutines/selects/SelectBuilderImpl : kotlinx/coroutines/internal/LockFreeLinkedListHead, kotlin/coroutines/Continuation, kotlin/coroutines/jvm/internal/CoroutineStackFrame, kotlinx/coroutines/selects/SelectBuilder, kotlinx/coroutines/selects/SelectInstance {
1198+
public final class kotlinx/coroutines/selects/SelectBuilderImpl : kotlinx/coroutines/selects/SelectImplementation {
11941199
public fun <init> (Lkotlin/coroutines/Continuation;)V
1195-
public fun disposeOnSelect (Lkotlinx/coroutines/DisposableHandle;)V
1196-
public fun getCallerFrame ()Lkotlin/coroutines/jvm/internal/CoroutineStackFrame;
1197-
public fun getCompletion ()Lkotlin/coroutines/Continuation;
1198-
public fun getContext ()Lkotlin/coroutines/CoroutineContext;
11991200
public final fun getResult ()Ljava/lang/Object;
1200-
public fun getStackTraceElement ()Ljava/lang/StackTraceElement;
1201+
public final fun getUCont ()Lkotlin/coroutines/Continuation;
12011202
public final fun handleBuilderException (Ljava/lang/Throwable;)V
1202-
public fun invoke (Lkotlinx/coroutines/selects/SelectClause0;Lkotlin/jvm/functions/Function1;)V
1203-
public fun invoke (Lkotlinx/coroutines/selects/SelectClause1;Lkotlin/jvm/functions/Function2;)V
1204-
public fun invoke (Lkotlinx/coroutines/selects/SelectClause2;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
1205-
public fun invoke (Lkotlinx/coroutines/selects/SelectClause2;Lkotlin/jvm/functions/Function2;)V
1206-
public fun isSelected ()Z
1207-
public fun onTimeout (JLkotlin/jvm/functions/Function1;)V
1208-
public fun performAtomicTrySelect (Lkotlinx/coroutines/internal/AtomicDesc;)Ljava/lang/Object;
1209-
public fun resumeSelectWithException (Ljava/lang/Throwable;)V
1210-
public fun resumeWith (Ljava/lang/Object;)V
1211-
public fun toString ()Ljava/lang/String;
1212-
public fun trySelect ()Z
1213-
public fun trySelectOther (Lkotlinx/coroutines/internal/LockFreeLinkedListNode$PrepareOp;)Ljava/lang/Object;
12141203
}
12151204

1216-
public abstract interface class kotlinx/coroutines/selects/SelectClause0 {
1217-
public abstract fun registerSelectClause0 (Lkotlinx/coroutines/selects/SelectInstance;Lkotlin/jvm/functions/Function1;)V
1205+
public abstract interface class kotlinx/coroutines/selects/SelectClause {
1206+
public abstract fun getClauseObject ()Ljava/lang/Object;
1207+
public abstract fun getProcessResFunc ()Lkotlin/jvm/functions/Function3;
1208+
public abstract fun getRegFunc ()Lkotlin/jvm/functions/Function3;
1209+
}
1210+
1211+
public abstract interface class kotlinx/coroutines/selects/SelectClause0 : kotlinx/coroutines/selects/SelectClause {
1212+
}
1213+
1214+
public final class kotlinx/coroutines/selects/SelectClause0Impl : kotlinx/coroutines/selects/SelectClause0 {
1215+
public fun <init> (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)V
1216+
public fun getClauseObject ()Ljava/lang/Object;
1217+
public fun getProcessResFunc ()Lkotlin/jvm/functions/Function3;
1218+
public fun getRegFunc ()Lkotlin/jvm/functions/Function3;
12181219
}
12191220

1220-
public abstract interface class kotlinx/coroutines/selects/SelectClause1 {
1221-
public abstract fun registerSelectClause1 (Lkotlinx/coroutines/selects/SelectInstance;Lkotlin/jvm/functions/Function2;)V
1221+
public abstract interface class kotlinx/coroutines/selects/SelectClause1 : kotlinx/coroutines/selects/SelectClause {
12221222
}
12231223

1224-
public abstract interface class kotlinx/coroutines/selects/SelectClause2 {
1225-
public abstract fun registerSelectClause2 (Lkotlinx/coroutines/selects/SelectInstance;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
1224+
public final class kotlinx/coroutines/selects/SelectClause1Impl : kotlinx/coroutines/selects/SelectClause1 {
1225+
public fun <init> (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;)V
1226+
public fun getClauseObject ()Ljava/lang/Object;
1227+
public fun getProcessResFunc ()Lkotlin/jvm/functions/Function3;
1228+
public fun getRegFunc ()Lkotlin/jvm/functions/Function3;
1229+
}
1230+
1231+
public abstract interface class kotlinx/coroutines/selects/SelectClause2 : kotlinx/coroutines/selects/SelectClause {
1232+
}
1233+
1234+
public final class kotlinx/coroutines/selects/SelectClause2Impl : kotlinx/coroutines/selects/SelectClause2 {
1235+
public fun <init> (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;)V
1236+
public fun getClauseObject ()Ljava/lang/Object;
1237+
public fun getProcessResFunc ()Lkotlin/jvm/functions/Function3;
1238+
public fun getRegFunc ()Lkotlin/jvm/functions/Function3;
1239+
}
1240+
1241+
public class kotlinx/coroutines/selects/SelectImplementation : kotlinx/coroutines/selects/SelectBuilder, kotlinx/coroutines/selects/SelectInstance {
1242+
public fun <init> (Lkotlin/coroutines/CoroutineContext;)V
1243+
public fun doSelect (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
1244+
public fun getContext ()Lkotlin/coroutines/CoroutineContext;
1245+
public synthetic fun invoke (Ljava/lang/Object;)Ljava/lang/Object;
1246+
public fun invoke (Ljava/lang/Throwable;)V
1247+
public fun invoke (Lkotlinx/coroutines/selects/SelectClause0;Lkotlin/jvm/functions/Function1;)V
1248+
public fun invoke (Lkotlinx/coroutines/selects/SelectClause1;Lkotlin/jvm/functions/Function2;)V
1249+
public fun invoke (Lkotlinx/coroutines/selects/SelectClause2;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
1250+
public fun invoke (Lkotlinx/coroutines/selects/SelectClause2;Lkotlin/jvm/functions/Function2;)V
1251+
public fun invokeOnCompletion (Lkotlin/jvm/functions/Function0;)V
1252+
public synthetic fun onTimeout (JLkotlin/jvm/functions/Function1;)V
1253+
protected final fun register (Lkotlinx/coroutines/selects/SelectClause0;Lkotlin/jvm/functions/Function1;)V
1254+
protected final fun register (Lkotlinx/coroutines/selects/SelectClause1;Lkotlin/jvm/functions/Function2;)V
1255+
protected final fun register (Lkotlinx/coroutines/selects/SelectClause2;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
1256+
public fun selectInRegistrationPhase (Ljava/lang/Object;)V
1257+
public fun trySelect (Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z
12261258
}
12271259

12281260
public abstract interface class kotlinx/coroutines/selects/SelectInstance {
1229-
public abstract fun disposeOnSelect (Lkotlinx/coroutines/DisposableHandle;)V
1230-
public abstract fun getCompletion ()Lkotlin/coroutines/Continuation;
1231-
public abstract fun isSelected ()Z
1232-
public abstract fun performAtomicTrySelect (Lkotlinx/coroutines/internal/AtomicDesc;)Ljava/lang/Object;
1233-
public abstract fun resumeSelectWithException (Ljava/lang/Throwable;)V
1234-
public abstract fun trySelect ()Z
1235-
public abstract fun trySelectOther (Lkotlinx/coroutines/internal/LockFreeLinkedListNode$PrepareOp;)Ljava/lang/Object;
1261+
public abstract fun getContext ()Lkotlin/coroutines/CoroutineContext;
1262+
public abstract fun invokeOnCompletion (Lkotlin/jvm/functions/Function0;)V
1263+
public abstract fun selectInRegistrationPhase (Ljava/lang/Object;)V
1264+
public abstract fun trySelect (Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z
1265+
}
1266+
1267+
public final class kotlinx/coroutines/selects/SelectInstance$DefaultImpls {
1268+
public static synthetic fun trySelect$default (Lkotlinx/coroutines/selects/SelectInstance;Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Z
12361269
}
12371270

12381271
public final class kotlinx/coroutines/selects/SelectKt {
1239-
public static final fun onTimeout-8Mi8wO0 (Lkotlinx/coroutines/selects/SelectBuilder;JLkotlin/jvm/functions/Function1;)V
12401272
public static final fun select (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
12411273
}
12421274

12431275
public final class kotlinx/coroutines/selects/SelectUnbiasedKt {
12441276
public static final fun selectUnbiased (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
12451277
}
12461278

1247-
public final class kotlinx/coroutines/selects/UnbiasedSelectBuilderImpl : kotlinx/coroutines/selects/SelectBuilder {
1279+
public final class kotlinx/coroutines/selects/UnbiasedSelectBuilderImpl : kotlinx/coroutines/selects/UnbiasedSelectImplementation {
12481280
public fun <init> (Lkotlin/coroutines/Continuation;)V
1249-
public final fun getClauses ()Ljava/util/ArrayList;
1250-
public final fun getInstance ()Lkotlinx/coroutines/selects/SelectBuilderImpl;
1281+
public final fun getUCont ()Lkotlin/coroutines/Continuation;
12511282
public final fun handleBuilderException (Ljava/lang/Throwable;)V
12521283
public final fun initSelectResult ()Ljava/lang/Object;
1284+
}
1285+
1286+
public class kotlinx/coroutines/selects/UnbiasedSelectImplementation : kotlinx/coroutines/selects/SelectImplementation {
1287+
public fun <init> (Lkotlin/coroutines/CoroutineContext;)V
1288+
public fun doSelect (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
12531289
public fun invoke (Lkotlinx/coroutines/selects/SelectClause0;Lkotlin/jvm/functions/Function1;)V
12541290
public fun invoke (Lkotlinx/coroutines/selects/SelectClause1;Lkotlin/jvm/functions/Function2;)V
12551291
public fun invoke (Lkotlinx/coroutines/selects/SelectClause2;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
1256-
public fun invoke (Lkotlinx/coroutines/selects/SelectClause2;Lkotlin/jvm/functions/Function2;)V
1257-
public fun onTimeout (JLkotlin/jvm/functions/Function1;)V
12581292
}
12591293

12601294
public final class kotlinx/coroutines/selects/WhileSelectKt {

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

+2-4
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,10 @@ public fun <T> CoroutineScope.async(
9696
private open class DeferredCoroutine<T>(
9797
parentContext: CoroutineContext,
9898
active: Boolean
99-
) : AbstractCoroutine<T>(parentContext, true, active = active), Deferred<T>, SelectClause1<T> {
99+
) : AbstractCoroutine<T>(parentContext, true, active = active), Deferred<T> {
100100
override fun getCompleted(): T = getCompletedInternal() as T
101101
override suspend fun await(): T = awaitInternal() as T
102-
override val onAwait: SelectClause1<T> get() = this
103-
override fun <R> registerSelectClause1(select: SelectInstance<R>, block: suspend (T) -> R) =
104-
registerSelectClause1Internal(select, block)
102+
override val onAwait: SelectClause1<T> get() = onAwaitInternal as SelectClause1<T>
105103
}
106104

107105
private class LazyDeferredCoroutine<T>(

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

+2-4
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,12 @@ public fun <T> CompletableDeferred(value: T): CompletableDeferred<T> = Completab
7979
@Suppress("UNCHECKED_CAST")
8080
private class CompletableDeferredImpl<T>(
8181
parent: Job?
82-
) : JobSupport(true), CompletableDeferred<T>, SelectClause1<T> {
82+
) : JobSupport(true), CompletableDeferred<T> {
8383
init { initParentJob(parent) }
8484
override val onCancelComplete get() = true
8585
override fun getCompleted(): T = getCompletedInternal() as T
8686
override suspend fun await(): T = awaitInternal() as T
87-
override val onAwait: SelectClause1<T> get() = this
88-
override fun <R> registerSelectClause1(select: SelectInstance<R>, block: suspend (T) -> R) =
89-
registerSelectClause1Internal(select, block)
87+
override val onAwait: SelectClause1<T> get() = onAwaitInternal as SelectClause1<T>
9088

9189
override fun complete(value: T): Boolean =
9290
makeCompleting(value)

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

+34-73
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ package kotlinx.coroutines
77

88
import kotlinx.atomicfu.*
99
import kotlinx.coroutines.internal.*
10-
import kotlinx.coroutines.intrinsics.*
1110
import kotlinx.coroutines.selects.*
1211
import kotlin.coroutines.*
1312
import kotlin.coroutines.intrinsics.*
@@ -25,7 +24,7 @@ import kotlin.native.concurrent.*
2524
* @suppress **This is unstable API and it is subject to change.**
2625
*/
2726
@Deprecated(level = DeprecationLevel.ERROR, message = "This is internal API and may be removed in the future releases")
28-
public open class JobSupport constructor(active: Boolean) : Job, ChildJob, ParentJob, SelectClause0 {
27+
public open class JobSupport constructor(active: Boolean) : Job, ChildJob, ParentJob {
2928
final override val key: CoroutineContext.Key<*> get() = Job
3029

3130
/*
@@ -560,26 +559,18 @@ public open class JobSupport constructor(active: Boolean) : Job, ChildJob, Paren
560559
}
561560

562561
public final override val onJoin: SelectClause0
563-
get() = this
562+
get() = SelectClause0Impl(
563+
clauseObject = this@JobSupport,
564+
regFunc = JobSupport::registerSelectForOnJoin as RegistrationFunction
565+
)
564566

565-
// registerSelectJoin
566-
public final override fun <R> registerSelectClause0(select: SelectInstance<R>, block: suspend () -> R) {
567-
// fast-path -- check state and select/return if needed
568-
loopOnState { state ->
569-
if (select.isSelected) return
570-
if (state !is Incomplete) {
571-
// already complete -- select result
572-
if (select.trySelect()) {
573-
block.startCoroutineUnintercepted(select.completion)
574-
}
575-
return
576-
}
577-
if (startInternal(state) == 0) {
578-
// slow-path -- register waiter for completion
579-
select.disposeOnSelect(invokeOnCompletion(handler = SelectJoinOnCompletion(select, block).asHandler))
580-
return
581-
}
567+
private fun registerSelectForOnJoin(select: SelectInstance<*>, ignoredParam: Any?) {
568+
if (!joinInternal()) {
569+
select.selectInRegistrationPhase(Unit)
570+
return
582571
}
572+
val disposableHandle = invokeOnCompletion { select.trySelect(this@JobSupport, Unit) }
573+
select.invokeOnCompletion { disposableHandle.dispose() }
583574
}
584575

585576
/**
@@ -1234,46 +1225,36 @@ public open class JobSupport constructor(active: Boolean) : Job, ChildJob, Paren
12341225
cont.getResult()
12351226
}
12361227

1237-
/**
1238-
* @suppress **This is unstable API and it is subject to change.**
1239-
*/
1240-
// registerSelectAwaitInternal
1241-
@Suppress("UNCHECKED_CAST")
1242-
internal fun <T, R> registerSelectClause1Internal(select: SelectInstance<R>, block: suspend (T) -> R) {
1243-
// fast-path -- check state and select/return if needed
1244-
loopOnState { state ->
1245-
if (select.isSelected) return
1228+
1229+
internal val onAwaitInternal: SelectClause1<*> get() = SelectClause1Impl<Any?>(
1230+
clauseObject = this,
1231+
regFunc = JobSupport::onAwaitInternalRegFunc as RegistrationFunction,
1232+
processResFunc = JobSupport::onAwaitInternalProcessResFunc as ProcessResultFunction
1233+
)
1234+
1235+
private fun onAwaitInternalRegFunc(select: SelectInstance<*>, ignoredParam: Any?) {
1236+
while (true) {
1237+
val state = this.state
12461238
if (state !is Incomplete) {
1247-
// already complete -- select result
1248-
if (select.trySelect()) {
1249-
if (state is CompletedExceptionally) {
1250-
select.resumeSelectWithException(state.cause)
1251-
}
1252-
else {
1253-
block.startCoroutineUnintercepted(state.unboxState() as T, select.completion)
1254-
}
1255-
}
1239+
val result = if (state is CompletedExceptionally) state else state.unboxState()
1240+
select.selectInRegistrationPhase(result)
12561241
return
12571242
}
1258-
if (startInternal(state) == 0) {
1259-
// slow-path -- register waiter for completion
1260-
select.disposeOnSelect(invokeOnCompletion(handler = SelectAwaitOnCompletion(select, block).asHandler))
1261-
return
1243+
if (startInternal(state) >= 0) break // break unless needs to retry
1244+
}
1245+
val disposableHandle = invokeOnCompletion {
1246+
val state = this.state
1247+
if (state !is Incomplete) {
1248+
val result = if (state is CompletedExceptionally) state else state.unboxState()
1249+
select.trySelect(this, result)
12621250
}
12631251
}
1252+
select.invokeOnCompletion { disposableHandle.dispose() }
12641253
}
12651254

1266-
/**
1267-
* @suppress **This is unstable API and it is subject to change.**
1268-
*/
1269-
@Suppress("UNCHECKED_CAST")
1270-
internal fun <T, R> selectAwaitCompletion(select: SelectInstance<R>, block: suspend (T) -> R) {
1271-
val state = this.state
1272-
// Note: await is non-atomic (can be cancelled while dispatched)
1273-
if (state is CompletedExceptionally)
1274-
select.resumeSelectWithException(state.cause)
1275-
else
1276-
block.startCoroutineCancellable(state.unboxState() as T, select.completion)
1255+
private fun onAwaitInternalProcessResFunc(ignoredParam: Any?, result: Any?): Any? {
1256+
if (result is CompletedExceptionally) throw result.cause
1257+
return result
12771258
}
12781259
}
12791260

@@ -1420,26 +1401,6 @@ internal class DisposeOnCompletion(
14201401
override fun invoke(cause: Throwable?) = handle.dispose()
14211402
}
14221403

1423-
private class SelectJoinOnCompletion<R>(
1424-
private val select: SelectInstance<R>,
1425-
private val block: suspend () -> R
1426-
) : JobNode() {
1427-
override fun invoke(cause: Throwable?) {
1428-
if (select.trySelect())
1429-
block.startCoroutineCancellable(select.completion)
1430-
}
1431-
}
1432-
1433-
private class SelectAwaitOnCompletion<T, R>(
1434-
private val select: SelectInstance<R>,
1435-
private val block: suspend (T) -> R
1436-
) : JobNode() {
1437-
override fun invoke(cause: Throwable?) {
1438-
if (select.trySelect())
1439-
job.selectAwaitCompletion(select, block)
1440-
}
1441-
}
1442-
14431404
// -------- invokeOnCancellation nodes
14441405

14451406
/**

0 commit comments

Comments
 (0)