Skip to content

Commit 37a91e5

Browse files
committed
Job.cancel and ReceiveChannel.cancel now return unit instead of boolean
Fixes #713
1 parent ca98207 commit 37a91e5

File tree

17 files changed

+91
-58
lines changed

17 files changed

+91
-58
lines changed

binary-compatibility-validator/reference-public-api/kotlinx-coroutines-core.txt

+24-5
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public abstract interface class kotlinx/coroutines/ChildJob : kotlinx/coroutines
7676
}
7777

7878
public final class kotlinx/coroutines/ChildJob$DefaultImpls {
79+
public static synthetic fun cancel (Lkotlinx/coroutines/ChildJob;)Z
7980
public static fun fold (Lkotlinx/coroutines/ChildJob;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
8081
public static fun get (Lkotlinx/coroutines/ChildJob;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
8182
public static fun minusKey (Lkotlinx/coroutines/ChildJob;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
@@ -89,6 +90,7 @@ public abstract interface class kotlinx/coroutines/CompletableDeferred : kotlinx
8990
}
9091

9192
public final class kotlinx/coroutines/CompletableDeferred$DefaultImpls {
93+
public static synthetic fun cancel (Lkotlinx/coroutines/CompletableDeferred;)Z
9294
public static fun fold (Lkotlinx/coroutines/CompletableDeferred;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
9395
public static fun get (Lkotlinx/coroutines/CompletableDeferred;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
9496
public static fun minusKey (Lkotlinx/coroutines/CompletableDeferred;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
@@ -197,6 +199,7 @@ public abstract interface class kotlinx/coroutines/Deferred : kotlinx/coroutines
197199
}
198200

199201
public final class kotlinx/coroutines/Deferred$DefaultImpls {
202+
public static synthetic fun cancel (Lkotlinx/coroutines/Deferred;)Z
200203
public static fun fold (Lkotlinx/coroutines/Deferred;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
201204
public static fun get (Lkotlinx/coroutines/Deferred;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
202205
public static fun minusKey (Lkotlinx/coroutines/Deferred;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
@@ -260,7 +263,8 @@ public abstract interface annotation class kotlinx/coroutines/InternalCoroutines
260263
public abstract interface class kotlinx/coroutines/Job : kotlin/coroutines/CoroutineContext$Element {
261264
public static final field Key Lkotlinx/coroutines/Job$Key;
262265
public abstract fun attachChild (Lkotlinx/coroutines/ChildJob;)Lkotlinx/coroutines/ChildHandle;
263-
public abstract fun cancel ()Z
266+
public abstract fun cancel ()V
267+
public abstract synthetic fun cancel ()Z
264268
public abstract fun cancel (Ljava/lang/Throwable;)Z
265269
public abstract fun getCancellationException ()Ljava/util/concurrent/CancellationException;
266270
public abstract fun getChildren ()Lkotlin/sequences/Sequence;
@@ -276,6 +280,7 @@ public abstract interface class kotlinx/coroutines/Job : kotlin/coroutines/Corou
276280
}
277281

278282
public final class kotlinx/coroutines/Job$DefaultImpls {
283+
public static synthetic fun cancel (Lkotlinx/coroutines/Job;)Z
279284
public static synthetic fun cancel$default (Lkotlinx/coroutines/Job;Ljava/lang/Throwable;ILjava/lang/Object;)Z
280285
public static fun fold (Lkotlinx/coroutines/Job;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
281286
public static fun get (Lkotlinx/coroutines/Job;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
@@ -292,7 +297,8 @@ public final class kotlinx/coroutines/JobKt {
292297
public static final fun DisposableHandle (Lkotlin/jvm/functions/Function0;)Lkotlinx/coroutines/DisposableHandle;
293298
public static final fun Job (Lkotlinx/coroutines/Job;)Lkotlinx/coroutines/Job;
294299
public static synthetic fun Job$default (Lkotlinx/coroutines/Job;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
295-
public static final fun cancel (Lkotlin/coroutines/CoroutineContext;)Z
300+
public static final fun cancel (Lkotlin/coroutines/CoroutineContext;)V
301+
public static final synthetic fun cancel (Lkotlin/coroutines/CoroutineContext;)Z
296302
public static final fun cancel (Lkotlin/coroutines/CoroutineContext;Ljava/lang/Throwable;)Z
297303
public static synthetic fun cancel$default (Lkotlin/coroutines/CoroutineContext;Ljava/lang/Throwable;ILjava/lang/Object;)Z
298304
public static final fun cancelAndJoin (Lkotlinx/coroutines/Job;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
@@ -309,7 +315,8 @@ public final class kotlinx/coroutines/JobKt {
309315
public class kotlinx/coroutines/JobSupport : kotlinx/coroutines/ChildJob, kotlinx/coroutines/Job, kotlinx/coroutines/ParentJob, kotlinx/coroutines/selects/SelectClause0 {
310316
public fun <init> (Z)V
311317
public final fun attachChild (Lkotlinx/coroutines/ChildJob;)Lkotlinx/coroutines/ChildHandle;
312-
public fun cancel ()Z
318+
public fun cancel ()V
319+
public synthetic fun cancel ()Z
313320
public fun cancel (Ljava/lang/Throwable;)Z
314321
public fun childCancelled (Ljava/lang/Throwable;)Z
315322
public fun fold (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
@@ -349,7 +356,8 @@ public abstract class kotlinx/coroutines/MainCoroutineDispatcher : kotlinx/corou
349356
public final class kotlinx/coroutines/NonCancellable : kotlin/coroutines/AbstractCoroutineContextElement, kotlinx/coroutines/Job {
350357
public static final field INSTANCE Lkotlinx/coroutines/NonCancellable;
351358
public fun attachChild (Lkotlinx/coroutines/ChildJob;)Lkotlinx/coroutines/ChildHandle;
352-
public fun cancel ()Z
359+
public fun cancel ()V
360+
public synthetic fun cancel ()Z
353361
public fun cancel (Ljava/lang/Throwable;)Z
354362
public fun getCancellationException ()Ljava/util/concurrent/CancellationException;
355363
public fun getChildren ()Lkotlin/sequences/Sequence;
@@ -379,6 +387,7 @@ public abstract interface class kotlinx/coroutines/ParentJob : kotlinx/coroutine
379387
}
380388

381389
public final class kotlinx/coroutines/ParentJob$DefaultImpls {
390+
public static synthetic fun cancel (Lkotlinx/coroutines/ParentJob;)Z
382391
public static fun fold (Lkotlinx/coroutines/ParentJob;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
383392
public static fun get (Lkotlinx/coroutines/ParentJob;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element;
384393
public static fun minusKey (Lkotlinx/coroutines/ParentJob;Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext;
@@ -439,6 +448,10 @@ public abstract interface class kotlinx/coroutines/channels/ActorScope : kotlinx
439448
public abstract fun getChannel ()Lkotlinx/coroutines/channels/Channel;
440449
}
441450

451+
public final class kotlinx/coroutines/channels/ActorScope$DefaultImpls {
452+
public static synthetic fun cancel (Lkotlinx/coroutines/channels/ActorScope;)Z
453+
}
454+
442455
public abstract interface class kotlinx/coroutines/channels/BroadcastChannel : kotlinx/coroutines/channels/SendChannel {
443456
public abstract fun cancel (Ljava/lang/Throwable;)Z
444457
public abstract fun openSubscription ()Lkotlinx/coroutines/channels/ReceiveChannel;
@@ -466,6 +479,10 @@ public abstract interface class kotlinx/coroutines/channels/Channel : kotlinx/co
466479
public static final field UNLIMITED I
467480
}
468481

482+
public final class kotlinx/coroutines/channels/Channel$DefaultImpls {
483+
public static synthetic fun cancel (Lkotlinx/coroutines/channels/Channel;)Z
484+
}
485+
469486
public final class kotlinx/coroutines/channels/Channel$Factory {
470487
public static final field CONFLATED I
471488
public static final field RENDEZVOUS I
@@ -637,7 +654,8 @@ public abstract interface class kotlinx/coroutines/channels/ProducerScope : kotl
637654
}
638655

639656
public abstract interface class kotlinx/coroutines/channels/ReceiveChannel {
640-
public abstract fun cancel ()Z
657+
public abstract fun cancel ()V
658+
public abstract synthetic fun cancel ()Z
641659
public abstract fun cancel (Ljava/lang/Throwable;)Z
642660
public abstract fun getOnReceive ()Lkotlinx/coroutines/selects/SelectClause1;
643661
public abstract fun getOnReceiveOrNull ()Lkotlinx/coroutines/selects/SelectClause1;
@@ -650,6 +668,7 @@ public abstract interface class kotlinx/coroutines/channels/ReceiveChannel {
650668
}
651669

652670
public final class kotlinx/coroutines/channels/ReceiveChannel$DefaultImpls {
671+
public static synthetic fun cancel (Lkotlinx/coroutines/channels/ReceiveChannel;)Z
653672
public static synthetic fun cancel$default (Lkotlinx/coroutines/channels/ReceiveChannel;Ljava/lang/Throwable;ILjava/lang/Object;)Z
654673
}
655674

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

+25-9
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,19 @@ public interface Job : CoroutineContext.Element {
154154
*/
155155
public fun start(): Boolean
156156

157+
/**
158+
* @suppress
159+
*/
160+
@Suppress("INAPPLICABLE_JVM_NAME")
161+
@Deprecated(level = DeprecationLevel.HIDDEN, message = "Left here for binary compatibility")
162+
@JvmName("cancel")
163+
public fun cancel0(): Boolean = cancel(null)
164+
157165
/**
158166
* Cancels this job.
159-
* The result is `true` if this job was either cancelled as a result of this invocation
160-
* or was already being cancelled.
161-
* If job is already completed, method returns `false`.
167+
* See [Job] documentation for full explanation of cancellation machinery.
162168
*/
163-
public fun cancel(): Boolean
169+
public fun cancel(): Unit
164170

165171
/**
166172
* Cancels this job with an optional cancellation [cause].
@@ -499,13 +505,23 @@ public fun Job.cancelChildren(cause: Throwable? = null) {
499505
public val CoroutineContext.isActive: Boolean
500506
get() = this[Job]?.isActive == true
501507

508+
509+
/**
510+
* @suppress
511+
*/
512+
@JvmName("cancel")
513+
@Deprecated(message = "Binary compatibility", level = DeprecationLevel.HIDDEN)
514+
public fun CoroutineContext.cancel0(): Boolean {
515+
this[Job]?.cancel()
516+
return true
517+
}
518+
502519
/**
503-
* Cancels [Job] of this context. The result is `true` if the job was
504-
* cancelled as a result of this invocation or was already being cancelled and
505-
* `false` if there is no job in the context or if it was already completed. See [Job.cancel] for details.
520+
* Cancels [Job] of this context. See [Job.cancel] for details.
506521
*/
507-
public fun CoroutineContext.cancel(): Boolean =
508-
this[Job]?.cancel() ?: false
522+
public fun CoroutineContext.cancel(): Unit {
523+
this[Job]?.cancel()
524+
}
509525

510526
/**
511527
* Cancels [Job] of this context with an optional cancellation [cause]. The result is `true` if the job was

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -559,8 +559,9 @@ public open class JobSupport constructor(active: Boolean) : Job, ChildJob, Paren
559559
internal open val onCancelComplete: Boolean get() = false
560560

561561
// external cancel without cause, never invoked implicitly from internal machinery
562-
public override fun cancel(): Boolean =
562+
public override fun cancel(): Unit {
563563
cancel(null) // must delegate here, because some classes override cancel(x)
564+
}
564565

565566
// external cancel with (optional) cause, never invoked implicitly from internal machinery
566567
public override fun cancel(cause: Throwable?): Boolean =

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,13 @@ public object NonCancellable : AbstractCoroutineContextElement(Job), Job {
8888
NonDisposableHandle
8989

9090
/**
91-
* Always returns `false`.
91+
* Does nothing.
9292
* @suppress **This an internal API and should not be used from general code.**
9393
*/
9494
@InternalCoroutinesApi
95-
override fun cancel(): Boolean = false
95+
@Suppress("RETURN_TYPE_MISMATCH_ON_OVERRIDE")
96+
override fun cancel(): Unit {
97+
}
9698

9799
/**
98100
* Always returns `false`.

common/kotlinx-coroutines-core-common/src/channels/AbstractChannel.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,9 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
657657
return if (result === POLL_FAILED) null else receiveOrNullResult(result)
658658
}
659659

660-
override fun cancel(): Boolean = cancel(null)
660+
override fun cancel(): Unit {
661+
cancel(null)
662+
}
661663

662664
override fun cancel(cause: Throwable?): Boolean =
663665
close(cause).also {

common/kotlinx-coroutines-core-common/src/channels/Channel.kt

+11-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
package kotlinx.coroutines.channels
88

99
import kotlinx.coroutines.*
10-
import kotlinx.coroutines.channels.Channel.Factory.RENDEZVOUS
1110
import kotlinx.coroutines.channels.Channel.Factory.CONFLATED
11+
import kotlinx.coroutines.channels.Channel.Factory.RENDEZVOUS
1212
import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED
1313
import kotlinx.coroutines.selects.*
14+
import kotlin.jvm.*
1415

1516
/**
1617
* Sender's interface to [Channel].
@@ -239,15 +240,22 @@ public interface ReceiveChannel<out E> {
239240
/**
240241
* Cancels reception of remaining elements from this channel. This function closes the channel
241242
* and removes all buffered sent elements from it.
242-
* This function returns `true` if the channel was not closed previously, or `false` otherwise.
243243
*
244244
* Immediately after invocation of this function [isClosedForReceive] and
245245
* [isClosedForSend][SendChannel.isClosedForSend]
246246
* on the side of [SendChannel] start returning `true`, so all attempts to send to this channel
247247
* afterwards will throw [ClosedSendChannelException], while attempts to receive will throw
248248
* [ClosedReceiveChannelException].
249249
*/
250-
public fun cancel(): Boolean
250+
public fun cancel(): Unit
251+
252+
/**
253+
* @suppress
254+
*/
255+
@Suppress("INAPPLICABLE_JVM_NAME")
256+
@Deprecated(level = DeprecationLevel.HIDDEN, message = "Left here for binary compatibility")
257+
@JvmName("cancel")
258+
public fun cancel0(): Boolean = cancel(null)
251259

252260
/**
253261
* Cancels reception of remaining elements from this channel. This function closes the channel with

common/kotlinx-coroutines-core-common/src/channels/ChannelCoroutine.kt

+5-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ internal open class ChannelCoroutine<E>(
1616

1717
val channel: Channel<E> get() = this
1818

19-
override fun cancel() = cancel(null)
19+
override fun cancel(): Unit {
20+
cancel(null)
21+
}
22+
23+
override fun cancel0(): Boolean = cancel(null)
2024

2125
override fun cancel(cause: Throwable?): Boolean {
2226
val wasCancelled = _channel.cancel(cause)

common/kotlinx-coroutines-core-common/test/AsyncLazyTest.kt

+2-4
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,8 @@ class AsyncLazyTest : TestBase() {
150150
}
151151
expect(2)
152152
assertTrue(!d.isActive && !d.isCompleted)
153-
assertTrue(d.cancel())
153+
d.cancel()
154154
assertTrue(!d.isActive && d.isCompleted && d.isCancelled)
155-
assertTrue(!d.cancel())
156155
assertTrue(!d.start())
157156
finish(3)
158157
assertEquals(d.await(), 42) // await shall throw CancellationException
@@ -178,9 +177,8 @@ class AsyncLazyTest : TestBase() {
178177
yield() // yield to d
179178
expect(5)
180179
assertTrue(d.isActive && !d.isCompleted && !d.isCancelled)
181-
assertTrue(d.cancel())
180+
d.cancel()
182181
assertTrue(!d.isActive && d.isCancelled) // cancelling !
183-
assertTrue(d.cancel())
184182
assertTrue(!d.isActive && d.isCancelled) // still cancelling
185183
finish(6)
186184
assertEquals(d.await(), 42) // await shall throw CancellationException

common/kotlinx-coroutines-core-common/test/CompletableDeferredTest.kt

+1-10
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,6 @@ class CompletableDeferredTest : TestBase() {
4242
assertEquals(null, c.getCompletionExceptionOrNull())
4343
}
4444

45-
@Test
46-
fun testCancel() {
47-
val c = CompletableDeferred<String>()
48-
assertEquals(true, c.cancel())
49-
checkCancel(c)
50-
assertEquals(false, c.cancel())
51-
checkCancel(c)
52-
}
53-
5445
private fun checkCancel(c: CompletableDeferred<String>) {
5546
assertEquals(false, c.isActive)
5647
assertEquals(true, c.isCancelled)
@@ -121,7 +112,7 @@ class CompletableDeferredTest : TestBase() {
121112
val c = CompletableDeferred<String>(parent)
122113
checkFresh(c)
123114
assertEquals(true, parent.isActive)
124-
assertEquals(true, c.cancel())
115+
c.cancel()
125116
checkCancel(c)
126117
assertEquals(true, parent.isActive)
127118
}

common/kotlinx-coroutines-core-common/test/CoroutinesTest.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,9 @@ class CoroutinesTest : TestBase() {
199199
yield() // to job
200200
expect(4)
201201
assertTrue(job.isActive && !job.isCompleted)
202-
assertTrue(job.cancel()) // cancels job
202+
job.cancel() // cancels job
203203
expect(5) // still here
204204
assertTrue(!job.isActive && !job.isCompleted)
205-
assertTrue(job.cancel()) // second attempt returns true as well, job is still completing
206205
expect(6) // we're still here
207206
job.join() // join the job, let job complete its "finally" section
208207
expect(8)

common/kotlinx-coroutines-core-common/test/WithContextTest.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ class WithContextTest : TestBase() {
203203
withContext(wrapperDispatcher(coroutineContext)) {
204204
require(isActive)
205205
expect(5)
206-
require(job!!.cancel()) // cancel itself
206+
job!!.cancel()
207207
require(job!!.cancel(AssertionError())) // cancel again, no success here
208208
require(!isActive)
209209
throw TestException() // but throw a different exception
@@ -233,7 +233,7 @@ class WithContextTest : TestBase() {
233233
withContext(wrapperDispatcher(coroutineContext)) {
234234
require(isActive)
235235
expect(5)
236-
require(job!!.cancel()) // cancel itself
236+
job!!.cancel() // cancel itself
237237
require(job!!.cancel(AssertionError()))
238238
require(!isActive)
239239
}

common/kotlinx-coroutines-core-common/test/channels/TestChannelKind.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ private class ChannelViaBroadcast<E>(
5959
override suspend fun receiveOrNull(): E? = sub.receiveOrNull()
6060
override fun poll(): E? = sub.poll()
6161
override fun iterator(): ChannelIterator<E> = sub.iterator()
62-
override fun cancel(): Boolean = sub.cancel()
62+
override fun cancel(): Unit = sub.cancel()
6363
override fun cancel(cause: Throwable?): Boolean = sub.cancel(cause)
6464
override val onReceive: SelectClause1<E>
6565
get() = sub.onReceive

core/kotlinx-coroutines-core/test/AsyncJvmTest.kt

+1-4
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ class AsyncJvmTest : TestBase() {
2828
yield() // to async
2929
expect(4)
3030
check(d.isActive && !d.isCompleted && !d.isCancelled)
31-
check(d.cancel())
31+
d.cancel()
3232
check(!d.isActive && !d.isCompleted && d.isCancelled)
33-
check(d.cancel()) // second attempt still returns true (still cancelling)
3433
check(!d.isActive && !d.isCompleted && d.isCancelled)
3534
expect(5)
3635
try {
@@ -41,8 +40,6 @@ class AsyncJvmTest : TestBase() {
4140
check(e is CancellationException)
4241
}
4342
check(!d.isActive && d.isCompleted && d.isCancelled)
44-
check(!d.cancel()) // now cancel return false -- already cancelled
45-
check(!d.isActive && d.isCompleted && d.isCancelled)
4643
finish(8)
4744
}
4845
}

core/kotlinx-coroutines-core/test/JobDisposeStressTest.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,8 @@ class JobDisposeStressTest: TestBase() {
4949
threads += testThread("canceller") {
5050
while (!done) {
5151
val job = this.job ?: continue
52-
val result = job.cancel()
52+
job.cancel()
5353
// Always returns true, TestJob never completes
54-
check(result)
5554
}
5655
}
5756

core/kotlinx-coroutines-core/test/JoinStressTest.kt

-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ class JoinStressTest : TestBase() {
5050
barrier.await()
5151
exceptionalJob.cancel()
5252
++results[awaiterJob.await()]
53-
require(!exceptionalJob.cancel())
5453
}
5554

5655
// Check that concurrent cancellation of job which throws TestException without suspends doesn't suppress TestException
@@ -93,7 +92,6 @@ class JoinStressTest : TestBase() {
9392
assertTrue(cancellerResult)
9493
}
9594
++results[awaiterResult]
96-
require(!exceptionalJob.cancel())
9795

9896
if (cancellerResult) {
9997
++successfulCancellations

0 commit comments

Comments
 (0)