Skip to content

Commit 64be795

Browse files
authored
Merge pull request #1089 from Kotlin/version-1.2.0
Version 1.2.0
2 parents 5830d01 + 8c2606d commit 64be795

File tree

65 files changed

+2044
-630
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+2044
-630
lines changed

CHANGES.md

+16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# Change log for kotlinx.coroutines
22

3+
## Version 1.2.0
4+
5+
* Kotlin updated to 1.3.30.
6+
* New API: `CancellableContinuation.resume` with `onCancelling` lambda (#1044) to consistently handle closeable resources.
7+
* Play services task version updated to 16.0.1.
8+
* `ReceiveChannel.isEmpty` is no longer deprecated
9+
10+
A lot of `Flow` improvements:
11+
* Purity property is renamed to context preservation and became more restrictive.
12+
* `zip` and `combineLatest` operators.
13+
* Integration with RxJava2
14+
* `flatMap`, `merge` and `concatenate` are replaced with `flattenConcat`, `flattenMerge`, `flatMapConcat` and `flatMapMerge`.
15+
* Various documentation improvements and minor bug fixes.
16+
17+
Note that `Flow` **is not** leaving its [preview status](/docs/compatibility.md#flow-preview-api).
18+
319
## Version 1.2.0-alpha-2
420

521
This release contains major [feature preview](/docs/compatibility.md#flow-preview-api): cold streams aka `Flow` (#254).

README.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
[![official JetBrains project](https://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
44
[![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0)
5-
[![Download](https://api.bintray.com/packages/kotlin/kotlinx/kotlinx.coroutines/images/download.svg?version=1.2.0-alpha-2) ](https://bintray.com/kotlin/kotlinx/kotlinx.coroutines/1.2.0-alpha-2)
5+
[![Download](https://api.bintray.com/packages/kotlin/kotlinx/kotlinx.coroutines/images/download.svg?version=1.2.0) ](https://bintray.com/kotlin/kotlinx/kotlinx.coroutines/1.2.0)
66

77
Library support for Kotlin coroutines with [multiplatform](#multiplatform) support.
8-
This is a companion version for Kotlin `1.3.21` release.
8+
This is a companion version for Kotlin `1.3.30` release.
99

1010
```kotlin
1111
GlobalScope.launch {
@@ -75,15 +75,15 @@ Add dependencies (you can also add other modules that you need):
7575
<dependency>
7676
<groupId>org.jetbrains.kotlinx</groupId>
7777
<artifactId>kotlinx-coroutines-core</artifactId>
78-
<version>1.2.0-alpha-2</version>
78+
<version>1.2.0</version>
7979
</dependency>
8080
```
8181

8282
And make sure that you use the latest Kotlin version:
8383

8484
```xml
8585
<properties>
86-
<kotlin.version>1.3.21</kotlin.version>
86+
<kotlin.version>1.3.30</kotlin.version>
8787
</properties>
8888
```
8989

@@ -93,15 +93,15 @@ Add dependencies (you can also add other modules that you need):
9393

9494
```groovy
9595
dependencies {
96-
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.0-alpha-2'
96+
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.0'
9797
}
9898
```
9999

100100
And make sure that you use the latest Kotlin version:
101101

102102
```groovy
103103
buildscript {
104-
ext.kotlin_version = '1.3.21'
104+
ext.kotlin_version = '1.3.30'
105105
}
106106
```
107107

@@ -119,15 +119,15 @@ Add dependencies (you can also add other modules that you need):
119119

120120
```groovy
121121
dependencies {
122-
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.0-alpha-2")
122+
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.0")
123123
}
124124
```
125125

126126
And make sure that you use the latest Kotlin version:
127127

128128
```groovy
129129
plugins {
130-
kotlin("jvm") version "1.3.21"
130+
kotlin("jvm") version "1.3.30"
131131
}
132132
```
133133

@@ -147,7 +147,7 @@ Add [`kotlinx-coroutines-android`](ui/kotlinx-coroutines-android)
147147
module as dependency when using `kotlinx.coroutines` on Android:
148148

149149
```groovy
150-
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.0-alpha-2'
150+
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.0'
151151
```
152152
This gives you access to Android [Dispatchers.Main](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-android/kotlinx.coroutines.android/kotlinx.coroutines.-dispatchers/index.html)
153153
coroutine dispatcher and also makes sure that in case of crashed coroutine with unhandled exception this

RELEASE.md

+8-4
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,18 @@ To release new `<version>` of `kotlinx-coroutines`:
6363

6464
5. Announce new release in [Slack](https://kotlinlang.slack.com)
6565

66-
6. Switch into `develop` branch:<br>
66+
6. Create a ticket to update coroutines version on [try.kotlinlang.org](try.kotlinlang.org).
67+
* Use [KT-30870](https://youtrack.jetbrains.com/issue/KT-30870) as a template
68+
* This step should be skipped for eap versions that are not merged to `master`
69+
70+
7. Switch into `develop` branch:<br>
6771
`git checkout develop`
6872

69-
7. Fetch the latest `master`:<br>
73+
8. Fetch the latest `master`:<br>
7074
`git fetch`
7175

72-
8. Merge release from `master`:<br>
76+
9. Merge release from `master`:<br>
7377
`git merge origin/master`
7478

75-
9. Push updates to `develop`:<br>
79+
10. Push updates to `develop`:<br>
7680
`git push`

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

+14-11
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public abstract interface class kotlinx/coroutines/CancellableContinuation : kot
4040
public abstract fun isActive ()Z
4141
public abstract fun isCancelled ()Z
4242
public abstract fun isCompleted ()Z
43+
public abstract fun resume (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
4344
public abstract fun resumeUndispatched (Lkotlinx/coroutines/CoroutineDispatcher;Ljava/lang/Object;)V
4445
public abstract fun resumeUndispatchedWithException (Lkotlinx/coroutines/CoroutineDispatcher;Ljava/lang/Throwable;)V
4546
public abstract fun tryResume (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
@@ -58,20 +59,18 @@ public class kotlinx/coroutines/CancellableContinuationImpl : kotlin/coroutines/
5859
public fun getCallerFrame ()Lkotlin/coroutines/jvm/internal/CoroutineStackFrame;
5960
public fun getContext ()Lkotlin/coroutines/CoroutineContext;
6061
public fun getContinuationCancellationCause (Lkotlinx/coroutines/Job;)Ljava/lang/Throwable;
61-
public final fun getDelegate ()Lkotlin/coroutines/Continuation;
6262
public final fun getResult ()Ljava/lang/Object;
6363
public fun getStackTraceElement ()Ljava/lang/StackTraceElement;
64-
public fun getSuccessfulResult (Ljava/lang/Object;)Ljava/lang/Object;
6564
public synthetic fun initCancellability ()V
6665
public fun invokeOnCancellation (Lkotlin/jvm/functions/Function1;)V
6766
public fun isActive ()Z
6867
public fun isCancelled ()Z
6968
public fun isCompleted ()Z
7069
protected fun nameString ()Ljava/lang/String;
70+
public fun resume (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V
7171
public fun resumeUndispatched (Lkotlinx/coroutines/CoroutineDispatcher;Ljava/lang/Object;)V
7272
public fun resumeUndispatchedWithException (Lkotlinx/coroutines/CoroutineDispatcher;Ljava/lang/Throwable;)V
7373
public fun resumeWith (Ljava/lang/Object;)V
74-
public fun takeState ()Ljava/lang/Object;
7574
public fun toString ()Ljava/lang/String;
7675
public fun tryResume (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
7776
public fun tryResumeWithException (Ljava/lang/Throwable;)Ljava/lang/Object;
@@ -794,8 +793,7 @@ public final class kotlinx/coroutines/flow/FlowKt {
794793
public static final fun broadcastIn (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/CoroutineScope;ILkotlinx/coroutines/CoroutineStart;)Lkotlinx/coroutines/channels/BroadcastChannel;
795794
public static synthetic fun broadcastIn$default (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/CoroutineScope;ILkotlinx/coroutines/CoroutineStart;ILjava/lang/Object;)Lkotlinx/coroutines/channels/BroadcastChannel;
796795
public static final fun collect (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
797-
public static final fun concatenate (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
798-
public static final fun concatenate (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
796+
public static final fun combineLatest (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/flow/Flow;
799797
public static final fun count (Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
800798
public static final fun count (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
801799
public static final fun delayEach (Lkotlinx/coroutines/flow/Flow;J)Lkotlinx/coroutines/flow/Flow;
@@ -808,8 +806,12 @@ public final class kotlinx/coroutines/flow/FlowKt {
808806
public static final fun filter (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
809807
public static final fun filterNot (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
810808
public static final fun filterNotNull (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
811-
public static final fun flatMap (Lkotlinx/coroutines/flow/Flow;IILkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
812-
public static synthetic fun flatMap$default (Lkotlinx/coroutines/flow/Flow;IILkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
809+
public static final fun flatMapConcat (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
810+
public static final fun flatMapMerge (Lkotlinx/coroutines/flow/Flow;IILkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
811+
public static synthetic fun flatMapMerge$default (Lkotlinx/coroutines/flow/Flow;IILkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
812+
public static final fun flattenConcat (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
813+
public static final fun flattenMerge (Lkotlinx/coroutines/flow/Flow;II)Lkotlinx/coroutines/flow/Flow;
814+
public static synthetic fun flattenMerge$default (Lkotlinx/coroutines/flow/Flow;IIILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
813815
public static final fun flow (Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
814816
public static final fun flowOf ([Ljava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
815817
public static final fun flowOn (Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/CoroutineContext;I)Lkotlinx/coroutines/flow/Flow;
@@ -821,8 +823,6 @@ public final class kotlinx/coroutines/flow/FlowKt {
821823
public static final fun fold (Lkotlinx/coroutines/flow/Flow;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
822824
public static final fun map (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
823825
public static final fun mapNotNull (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
824-
public static final fun merge (Ljava/lang/Iterable;II)Lkotlinx/coroutines/flow/Flow;
825-
public static synthetic fun merge$default (Ljava/lang/Iterable;IIILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
826826
public static final fun onEach (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
827827
public static final fun onErrorCollect (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/flow/Flow;
828828
public static synthetic fun onErrorCollect$default (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
@@ -844,14 +844,17 @@ public final class kotlinx/coroutines/flow/FlowKt {
844844
public static synthetic fun toSet$default (Lkotlinx/coroutines/flow/Flow;Ljava/util/Set;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
845845
public static final fun transform (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/flow/Flow;
846846
public static final fun unsafeFlow (Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
847+
public static final fun zip (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/flow/Flow;
847848
}
848849

849850
public final class kotlinx/coroutines/flow/MigrationKt {
850851
public static final fun BehaviourSubject ()Ljava/lang/Object;
851852
public static final fun PublishSubject ()Ljava/lang/Object;
852853
public static final fun ReplaySubject ()Ljava/lang/Object;
853-
public static final fun concat (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
854854
public static final fun concatMap (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/flow/Flow;
855+
public static final fun flatMap (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
856+
public static final fun flatten (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
857+
public static final fun merge (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
855858
public static final fun observeOn (Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/CoroutineContext;)Lkotlinx/coroutines/flow/Flow;
856859
public static final fun onErrorResume (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
857860
public static final fun publishOn (Lkotlinx/coroutines/flow/Flow;Lkotlin/coroutines/CoroutineContext;)Lkotlinx/coroutines/flow/Flow;
@@ -863,7 +866,7 @@ public final class kotlinx/coroutines/flow/MigrationKt {
863866
}
864867

865868
public final class kotlinx/coroutines/flow/internal/SafeCollector : kotlinx/coroutines/flow/FlowCollector {
866-
public fun <init> (Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/ContinuationInterceptor;)V
869+
public fun <init> (Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/CoroutineContext;)V
867870
public fun emit (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
868871
}
869872

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

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public final class kotlinx/coroutines/rx2/RxConvertKt {
2828
public static final fun asMaybe (Lkotlinx/coroutines/Deferred;Lkotlin/coroutines/CoroutineContext;)Lio/reactivex/Maybe;
2929
public static final fun asObservable (Lkotlinx/coroutines/channels/ReceiveChannel;Lkotlin/coroutines/CoroutineContext;)Lio/reactivex/Observable;
3030
public static final fun asSingle (Lkotlinx/coroutines/Deferred;Lkotlin/coroutines/CoroutineContext;)Lio/reactivex/Single;
31+
public static final fun from (Lkotlinx/coroutines/flow/Flow;)Lio/reactivex/Flowable;
32+
public static final fun from (Lkotlinx/coroutines/flow/Flow;)Lio/reactivex/Observable;
3133
}
3234

3335
public final class kotlinx/coroutines/rx2/RxFlowableKt {

gradle.properties

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
# Kotlin
2-
version=1.2.0-alpha-2-SNAPSHOT
2+
version=1.2.0-SNAPSHOT
33
group=org.jetbrains.kotlinx
4-
kotlin_version=1.3.21
4+
kotlin_version=1.3.30
55

66
# Dependencies
77
junit_version=4.12
8-
atomicFU_version=0.12.2
8+
atomicFU_version=0.12.3
99
html_version=0.6.8
1010
lincheck_version=2.0
1111
dokka_version=0.9.16-rdev-2-mpp-hacks
1212
bintray_version=1.8.4-jetbrains-5
1313
byte_buddy_version=1.9.3
1414
reactor_vesion=3.2.5.RELEASE
15+
reactive_streams_version=1.0.2
1516
artifactory_plugin_version=4.7.3
1617

1718
# JS

integration/kotlinx-coroutines-play-services/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import java.util.zip.ZipFile
77
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
88
*/
99

10-
ext.tasks_version = '15.0.1'
10+
ext.tasks_version = '16.0.1'
1111

1212
def attr = Attribute.of("artifactType", String.class)
1313
configurations {

integration/kotlinx-coroutines-play-services/src/Tasks.kt

+8-4
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ public fun <T> Task<T>.asDeferred(): Deferred<T> {
5050
if (isComplete) {
5151
val e = exception
5252
return if (e == null) {
53-
CompletableDeferred<T>().apply { if (isCanceled) cancel() else complete(result) }
53+
@Suppress("UNCHECKED_CAST")
54+
CompletableDeferred<T>().apply { if (isCanceled) cancel() else complete(result as T) }
5455
} else {
5556
CompletableDeferred<T>().apply { completeExceptionally(e) }
5657
}
@@ -60,7 +61,8 @@ public fun <T> Task<T>.asDeferred(): Deferred<T> {
6061
addOnCompleteListener {
6162
val e = it.exception
6263
if (e == null) {
63-
if (isCanceled) result.cancel() else result.complete(it.result)
64+
@Suppress("UNCHECKED_CAST")
65+
if (isCanceled) result.cancel() else result.complete(it.result as T)
6466
} else {
6567
result.completeExceptionally(e)
6668
}
@@ -83,7 +85,8 @@ public suspend fun <T> Task<T>.await(): T {
8385
if (isCanceled) {
8486
throw CancellationException("Task $this was cancelled normally.")
8587
} else {
86-
result
88+
@Suppress("UNCHECKED_CAST")
89+
result as T
8790
}
8891
} else {
8992
throw e
@@ -94,7 +97,8 @@ public suspend fun <T> Task<T>.await(): T {
9497
addOnCompleteListener {
9598
val e = exception
9699
if (e == null) {
97-
if (isCanceled) cont.cancel() else cont.resume(result)
100+
@Suppress("UNCHECKED_CAST")
101+
if (isCanceled) cont.cancel() else cont.resume(result as T)
98102
} else {
99103
cont.resumeWithException(e)
100104
}

integration/kotlinx-coroutines-play-services/test/TaskTest.kt

+5
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ class TaskTest : TestBase() {
9292
assertEquals(42, deferred.await())
9393
}
9494

95+
@Test
96+
fun testNullResultTaskAsDeferred() = runTest {
97+
assertNull(Tasks.forResult(null).asDeferred().await())
98+
}
99+
95100
@Test
96101
fun testCancelledTaskAsDeferred() = runTest {
97102
val deferred = Tasks.forCanceled<Int>().asDeferred()

kotlinx-coroutines-core/README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ Synchronization primitives (mutex).
7070

7171
# Package kotlinx.coroutines.channels
7272

73-
Channels -- non-blocking primitives for communicating a stream of elements between coroutines.
73+
Channels &mdash; non-blocking primitives for communicating a stream of elements between coroutines.
74+
75+
# Package kotlinx.coroutines.flow
76+
77+
Flow &mdash; asynchronous cold stream of elements.
7478

7579
# Package kotlinx.coroutines.selects
7680

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

+36-2
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,16 @@ public interface CancellableContinuation<in T> : Continuation<T> {
123123
* with cancellation exception. Otherwise, the handler will be invoked once on cancellation if this
124124
* continuation is cancelled.
125125
*
126-
* Installed [handler] should not throw any exceptions. If it does, they will get caught,
127-
* wrapped into [CompletionHandlerException], and rethrown, potentially causing the crash of unrelated code.
126+
* Installed [handler] should not throw any exceptions.
127+
* If it does, they will get caught, wrapped into [CompletionHandlerException] and
128+
* processed as uncaught exception in the context of the current coroutine
129+
* (see [CoroutineExceptionHandler]).
128130
*
129131
* At most one [handler] can be installed on one continuation.
132+
*
133+
* **Note**: Implementation of `CompletionHandler` must be fast, non-blocking, and thread-safe.
134+
* This handler can be invoked concurrently with the surrounding code.
135+
* There is no guarantee on the execution context in which the [handler] is invoked.
130136
*/
131137
public fun invokeOnCancellation(handler: CompletionHandler)
132138

@@ -151,6 +157,34 @@ public interface CancellableContinuation<in T> : Continuation<T> {
151157
*/
152158
@ExperimentalCoroutinesApi
153159
public fun CoroutineDispatcher.resumeUndispatchedWithException(exception: Throwable)
160+
161+
/**
162+
* Resumes this continuation with a given [value] and calls the specified [onCancellation]
163+
* handler when resumed too late (when continuation was already cancelled) or when resumed
164+
* successfully (before cancellation), but coroutine's job was cancelled before it had a
165+
* chance to run in its dispatcher, so that suspended function threw an exception
166+
* instead of returning this value.
167+
*
168+
* Installed [onCancellation] handler should not throw any exceptions.
169+
* If it does, they will get caught, wrapped into [CompletionHandlerException] and
170+
* processed as uncaught exception in the context of the current coroutine
171+
* (see [CoroutineExceptionHandler]).
172+
*
173+
* This function shall be used when resuming with a resource that must be closed by the
174+
* code that had called the corresponding suspending function, e.g.:
175+
*
176+
* ```
177+
* continuation.resume(resource) {
178+
* resource.close()
179+
* }
180+
* ```
181+
*
182+
* **Note**: Implementation of [onCancellation] handler must be fast, non-blocking, and thread-safe.
183+
* This handler can be invoked concurrently with the surrounding code.
184+
* There is no guarantee on the execution context in which the [onCancellation] handler is invoked.
185+
*/
186+
@ExperimentalCoroutinesApi // since 1.2.0, tentatively graduates in 1.3.0
187+
public fun resume(value: T, onCancellation: (cause: Throwable) -> Unit)
154188
}
155189

156190
/**

0 commit comments

Comments
 (0)