Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c5a579e

Browse files
authoredFeb 15, 2024
Merge pull request #4042 from Kotlin/dk-doc-improvements
Small documentation fixes
2 parents d0dabb9 + 83fa0b4 commit c5a579e

File tree

29 files changed

+371
-180
lines changed

29 files changed

+371
-180
lines changed
 

‎integration/kotlinx-coroutines-guava/src/ListenableFuture.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public fun <T> Deferred<T>.asListenableFuture(): ListenableFuture<T> {
216216
*
217217
* This suspend function is cancellable.
218218
*
219-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
219+
* If the [Job] of the current coroutine is cancelled while this suspending function is waiting, this function
220220
* stops waiting for the future and immediately resumes with [CancellationException][kotlinx.coroutines.CancellationException].
221221
*
222222
* This method is intended to be used with one-shot Futures, so on coroutine cancellation, the Future is cancelled as well.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ private fun <T> Task<T>.asDeferredImpl(cancellationTokenSource: CancellationToke
9494
* Awaits the completion of the task without blocking a thread.
9595
*
9696
* This suspending function is cancellable.
97-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
97+
* If the [Job] of the current coroutine is cancelled while this suspending function is waiting, this function
9898
* stops waiting for the completion stage and immediately resumes with [CancellationException].
9999
*
100100
* For bi-directional cancellation, an overload that accepts [CancellationTokenSource] can be used.
@@ -105,7 +105,7 @@ public suspend fun <T> Task<T>.await(): T = awaitImpl(null)
105105
* Awaits the completion of the task that is linked to the given [CancellationTokenSource] to control cancellation.
106106
*
107107
* This suspending function is cancellable and cancellation is bi-directional:
108-
* - If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
108+
* - If the [Job] of the current coroutine is cancelled while this suspending function is waiting, this function
109109
* cancels the [cancellationTokenSource] and throws a [CancellationException].
110110
* - If the task is cancelled, then this function will throw a [CancellationException].
111111
*

‎integration/kotlinx-coroutines-slf4j/src/MDCContext.kt

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,47 @@ public typealias MDCContextMap = Map<String, String>?
2828
* using [MDC.put]. These updates are going to be lost on the next suspension and
2929
* reinstalled to the MDC context that was captured or explicitly specified in
3030
* [contextMap] when this object was created on the next resumption.
31-
* Use `withContext(MDCContext()) { ... }` to capture updated map of MDC keys and values
32-
* for the specified block of code.
31+
*
32+
* For example, the following code will not work as expected:
33+
*
34+
* ```
35+
* launch(MDCContext()) {
36+
* MDC.put("key", "value") // This update will be lost
37+
* delay(100)
38+
* println(MDC.get("key")) // This will print null
39+
* }
40+
* ```
41+
*
42+
* Instead, you should use [withContext] to capture the updated MDC context:
43+
*
44+
* ```
45+
* launch(MDCContext()) {
46+
* MDC.put("key", "value") // This update will be captured
47+
* withContext(MDCContext()) {
48+
* delay(100)
49+
* println(MDC.get("key")) // This will print "value"
50+
* }
51+
* }
52+
* ```
53+
*
54+
* There is no way to implicitly propagate MDC context updates from inside the coroutine to the outer scope.
55+
* You have to capture the updated MDC context and restore it explicitly. For example:
56+
*
57+
* ```
58+
* MDC.put("a", "b")
59+
* val contextMap = withContext(MDCContext()) {
60+
* MDC.put("key", "value")
61+
* withContext(MDCContext()) {
62+
* MDC.put("key2", "value2")
63+
* withContext(MDCContext()) {
64+
* yield()
65+
* MDC.getCopyOfContextMap()
66+
* }
67+
* }
68+
* }
69+
* // contextMap contains: {"a"="b", "key"="value", "key2"="value2"}
70+
* MDC.setContextMap(contextMap)
71+
* ```
3372
*
3473
* @param contextMap the value of [MDC] context map.
3574
* Default value is the copy of the current thread's context map that is acquired via

‎integration/kotlinx-coroutines-slf4j/test/MDCContextTest.kt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,40 @@ class MDCContextTest : TestBase() {
105105
}
106106
}
107107
}
108+
109+
/** Tests that the initially captured MDC context gets restored after suspension. */
110+
@Test
111+
fun testSuspensionsUndoingMdcContextUpdates() = runTest {
112+
MDC.put("a", "b")
113+
withContext(MDCContext()) {
114+
MDC.put("key", "value")
115+
assertEquals("b", MDC.get("a"))
116+
yield()
117+
assertNull(MDC.get("key"))
118+
assertEquals("b", MDC.get("a"))
119+
}
120+
}
121+
122+
/** Tests capturing and restoring the MDC context. */
123+
@Test
124+
fun testRestoringMdcContext() = runTest {
125+
MDC.put("a", "b")
126+
val contextMap = withContext(MDCContext()) {
127+
MDC.put("key", "value")
128+
assertEquals("b", MDC.get("a"))
129+
withContext(MDCContext()) {
130+
assertEquals("value", MDC.get("key"))
131+
MDC.put("key2", "value2")
132+
assertEquals("value2", MDC.get("key2"))
133+
withContext(MDCContext()) {
134+
yield()
135+
MDC.getCopyOfContextMap()
136+
}
137+
}
138+
}
139+
MDC.setContextMap(contextMap)
140+
assertEquals("value2", MDC.get("key2"))
141+
assertEquals("value", MDC.get("key"))
142+
assertEquals("b", MDC.get("a"))
143+
}
108144
}

‎kotlinx-coroutines-core/common/src/Await.kt

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@ import kotlin.coroutines.*
1111
* This function is **not** equivalent to `deferreds.map { it.await() }` which fails only when it sequentially
1212
* gets to wait for the failing deferred, while this `awaitAll` fails immediately as soon as any of the deferreds fail.
1313
*
14-
* This suspending function is cancellable.
15-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting,
16-
* this function immediately resumes with [CancellationException].
17-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
18-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
14+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
15+
* suspending function is waiting, this function immediately resumes with [CancellationException].
16+
* There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
17+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
1918
*/
2019
public suspend fun <T> awaitAll(vararg deferreds: Deferred<T>): List<T> =
2120
if (deferreds.isEmpty()) emptyList() else AwaitAll(deferreds).await()
@@ -28,11 +27,10 @@ public suspend fun <T> awaitAll(vararg deferreds: Deferred<T>): List<T> =
2827
* This function is **not** equivalent to `this.map { it.await() }` which fails only when it sequentially
2928
* gets to wait for the failing deferred, while this `awaitAll` fails immediately as soon as any of the deferreds fail.
3029
*
31-
* This suspending function is cancellable.
32-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting,
33-
* this function immediately resumes with [CancellationException].
34-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
35-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
30+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
31+
* suspending function is waiting, this function immediately resumes with [CancellationException].
32+
* There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
33+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
3634
*/
3735
public suspend fun <T> Collection<Deferred<T>>.awaitAll(): List<T> =
3836
if (isEmpty()) emptyList() else AwaitAll(toTypedArray()).await()
@@ -41,23 +39,21 @@ public suspend fun <T> Collection<Deferred<T>>.awaitAll(): List<T> =
4139
* Suspends current coroutine until all given jobs are complete.
4240
* This method is semantically equivalent to joining all given jobs one by one with `jobs.forEach { it.join() }`.
4341
*
44-
* This suspending function is cancellable.
45-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting,
46-
* this function immediately resumes with [CancellationException].
47-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
48-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
42+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
43+
* suspending function is waiting, this function immediately resumes with [CancellationException].
44+
* There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
45+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
4946
*/
5047
public suspend fun joinAll(vararg jobs: Job): Unit = jobs.forEach { it.join() }
5148

5249
/**
5350
* Suspends current coroutine until all given jobs are complete.
5451
* This method is semantically equivalent to joining all given jobs one by one with `forEach { it.join() }`.
5552
*
56-
* This suspending function is cancellable.
57-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting,
58-
* this function immediately resumes with [CancellationException].
59-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
60-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
53+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
54+
* suspending function is waiting, this function immediately resumes with [CancellationException].
55+
* There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
56+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
6157
*/
6258
public suspend fun Collection<Job>.joinAll(): Unit = forEach { it.join() }
6359

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -238,25 +238,25 @@ public interface CancellableContinuation<in T> : Continuation<T> {
238238
*
239239
* This function provides **prompt cancellation guarantee**.
240240
* If the [Job] of the current coroutine was cancelled while this function was suspended it will not resume
241-
* successfully.
241+
* successfully, even if [CancellableContinuation.resume] was already invoked.
242242
*
243243
* The cancellation of the coroutine's job is generally asynchronous with respect to the suspended coroutine.
244-
* The suspended coroutine is resumed with the call it to its [Continuation.resumeWith] member function or to
244+
* The suspended coroutine is resumed with a call to its [Continuation.resumeWith] member function or to the
245245
* [resume][Continuation.resume] extension function.
246246
* However, when coroutine is resumed, it does not immediately start executing, but is passed to its
247247
* [CoroutineDispatcher] to schedule its execution when dispatcher's resources become available for execution.
248-
* The job's cancellation can happen both before, after, and concurrently with the call to `resume`. In any
249-
* case, prompt cancellation guarantees that the the coroutine will not resume its code successfully.
248+
* The job's cancellation can happen before, after, and concurrently with the call to `resume`. In any
249+
* case, prompt cancellation guarantees that the coroutine will not resume its code successfully.
250250
*
251251
* If the coroutine was resumed with an exception (for example, using [Continuation.resumeWithException] extension
252-
* function) and cancelled, then the resulting exception of the `suspendCancellableCoroutine` function is determined
253-
* by whichever action (exceptional resume or cancellation) that happened first.
252+
* function) and cancelled, then the exception thrown by the `suspendCancellableCoroutine` function is determined
253+
* by what happened first: exceptional resume or cancellation.
254254
*
255255
* ### Returning resources from a suspended coroutine
256256
*
257-
* As a result of a prompt cancellation guarantee, when a closeable resource
258-
* (like open file or a handle to another native resource) is returned from a suspended coroutine as a value
259-
* it can be lost when the coroutine is cancelled. In order to ensure that the resource can be properly closed
257+
* As a result of the prompt cancellation guarantee, when a closeable resource
258+
* (like open file or a handle to another native resource) is returned from a suspended coroutine as a value,
259+
* it can be lost when the coroutine is cancelled. To ensure that the resource can be properly closed
260260
* in this case, the [CancellableContinuation] interface provides two functions.
261261
*
262262
* - [invokeOnCancellation][CancellableContinuation.invokeOnCancellation] installs a handler that is called

‎kotlinx-coroutines-core/common/src/CoroutineScope.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,13 +220,13 @@ public object GlobalScope : CoroutineScope {
220220

221221
/**
222222
* Creates a [CoroutineScope] and calls the specified suspend block with this scope.
223-
* The provided scope inherits its [coroutineContext][CoroutineScope.coroutineContext] from the outer scope, but overrides
224-
* the context's [Job].
223+
* The provided scope inherits its [coroutineContext][CoroutineScope.coroutineContext] from the outer scope, using the
224+
* [Job] from that context as the parent for a new [Job].
225225
*
226226
* This function is designed for _concurrent decomposition_ of work. When any child coroutine in this scope fails,
227-
* this scope fails and all the rest of the children are cancelled (for a different behavior see [supervisorScope]).
228-
* This function returns as soon as the given block and all its children coroutines are completed.
229-
* A usage example of a scope looks like this:
227+
* this scope fails, cancelling all the other children (for a different behavior, see [supervisorScope]).
228+
* This function returns as soon as the given block and all its child coroutines are completed.
229+
* A usage of a scope looks like this:
230230
*
231231
* ```
232232
* suspend fun showSomeData() = coroutineScope {
@@ -248,8 +248,8 @@ public object GlobalScope : CoroutineScope {
248248
* 3) If the outer scope of `showSomeData` is cancelled, both started `async` and `withContext` blocks are cancelled.
249249
* 4) If the `async` block fails, `withContext` will be cancelled.
250250
*
251-
* The method may throw a [CancellationException] if the current job was cancelled externally
252-
* or may throw a corresponding unhandled [Throwable] if there is any unhandled exception in this scope
251+
* The method may throw a [CancellationException] if the current job was cancelled externally,
252+
* rethrow the exception thrown by [block], or throw an unhandled [Throwable] if there is one
253253
* (for example, from a crashed coroutine that was started with [launch][CoroutineScope.launch] in this scope).
254254
*/
255255
public suspend fun <R> coroutineScope(block: suspend CoroutineScope.() -> R): R {

‎kotlinx-coroutines-core/common/src/Deferred.kt

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,46 @@ import kotlinx.coroutines.selects.*
3333
public interface Deferred<out T> : Job {
3434

3535
/**
36-
* Awaits for completion of this value without blocking a thread and resumes when deferred computation is complete,
37-
* returning the resulting value or throwing the corresponding exception if the deferred was cancelled.
36+
* Awaits for completion of this value without blocking the thread and returns the resulting value or throws
37+
* the exception if the deferred was cancelled.
3838
*
39-
* This suspending function is cancellable.
40-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
41-
* immediately resumes with [CancellationException].
42-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
43-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
39+
* Unless the calling coroutine is cancelled, [await] will return the same result on each invocation:
40+
* if the [Deferred] completed successfully, [await] will return the same value every time;
41+
* if the [Deferred] completed exceptionally, [await] will rethrow the same exception.
4442
*
45-
* This function can be used in [select] invocation with [onAwait] clause.
46-
* Use [isCompleted] to check for completion of this deferred value without waiting.
43+
* This suspending function is itself cancellable: if the [Job] of the current coroutine is cancelled or completed
44+
* while this suspending function is waiting, this function immediately resumes with [CancellationException].
45+
*
46+
* This means that [await] can throw [CancellationException] in two cases:
47+
* - if the coroutine in which [await] was called got cancelled,
48+
* - or if the [Deferred] itself got completed with a [CancellationException].
49+
*
50+
* In both cases, the [CancellationException] will cancel the coroutine calling [await], unless it's caught.
51+
* The following idiom may be helpful to avoid this:
52+
* ```
53+
* try {
54+
* deferred.await()
55+
* } catch (e: CancellationException) {
56+
* currentCoroutineContext().ensureActive() // throws if the current coroutine was cancelled
57+
* processException(e) // if this line executes, the exception is the result of `await` itself
58+
* }
59+
* ```
60+
*
61+
* There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
62+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
63+
*
64+
* This function can be used in [select] invocations with an [onAwait] clause.
65+
* Use [isCompleted] to check for completion of this deferred value without waiting, and
66+
* [join] to wait for completion without returning the result.
4767
*/
4868
public suspend fun await(): T
4969

5070
/**
51-
* Clause for [select] expression of [await] suspending function that selects with the deferred value when it is
52-
* resolved. The [select] invocation fails if the deferred value completes exceptionally (either fails or
53-
* it cancelled).
71+
* Clause using the [await] suspending function as a [select] clause.
72+
* It selects with the deferred value when the [Deferred] completes.
73+
* If [Deferred] completes with an exception, the whole the [select] invocation fails with the same exception.
74+
* Note that, if [Deferred] completed with a [CancellationException], throwing it may have unintended
75+
* consequences. See [await] for details.
5476
*/
5577
public val onAwait: SelectClause1<T>
5678

‎kotlinx-coroutines-core/common/src/Delay.kt

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,10 @@ public suspend fun awaitCancellation(): Nothing = suspendCancellableCoroutine {}
106106
* Delays coroutine for at least the given time without blocking a thread and resumes it after a specified time.
107107
* If the given [timeMillis] is non-positive, this function returns immediately.
108108
*
109-
* This suspending function is cancellable.
110-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
111-
* immediately resumes with [CancellationException].
112-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
113-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
109+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
110+
* suspending function is waiting, this function immediately resumes with [CancellationException].
111+
* There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
112+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
114113
*
115114
* If you want to delay forever (until cancellation), consider using [awaitCancellation] instead.
116115
*
@@ -133,11 +132,10 @@ public suspend fun delay(timeMillis: Long) {
133132
* Delays coroutine for at least the given [duration] without blocking a thread and resumes it after the specified time.
134133
* If the given [duration] is non-positive, this function returns immediately.
135134
*
136-
* This suspending function is cancellable.
137-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
138-
* immediately resumes with [CancellationException].
139-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
140-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
135+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
136+
* suspending function is waiting, this function immediately resumes with [CancellationException].
137+
* There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
138+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
141139
*
142140
* If you want to delay forever (until cancellation), consider using [awaitCancellation] instead.
143141
*

‎kotlinx-coroutines-core/common/src/Supervisor.kt

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,8 @@ import kotlin.jvm.*
2020
* - A failure of a child job that was created using [launch][CoroutineScope.launch] can be handled via [CoroutineExceptionHandler] in the context.
2121
* - A failure of a child job that was created using [async][CoroutineScope.async] can be handled via [Deferred.await] on the resulting deferred value.
2222
*
23-
* If [parent] job is specified, then this supervisor job becomes a child job of its parent and is cancelled when its
24-
* parent fails or is cancelled. All this supervisor's children are cancelled in this case, too. The invocation of
25-
* [cancel][Job.cancel] with exception (other than [CancellationException]) on this supervisor job also cancels parent.
26-
*
27-
* @param parent an optional parent job.
23+
* If a [parent] job is specified, then this supervisor job becomes a child job of [parent] and is cancelled when the
24+
* parent fails or is cancelled. All this supervisor's children are cancelled in this case, too.
2825
*/
2926
@Suppress("FunctionName")
3027
public fun SupervisorJob(parent: Job? = null) : CompletableJob = SupervisorJobImpl(parent)
@@ -36,15 +33,16 @@ public fun SupervisorJob(parent: Job? = null) : CompletableJob = SupervisorJobIm
3633
public fun SupervisorJob0(parent: Job? = null) : Job = SupervisorJob(parent)
3734

3835
/**
39-
* Creates a [CoroutineScope] with [SupervisorJob] and calls the specified suspend block with this scope.
40-
* The provided scope inherits its [coroutineContext][CoroutineScope.coroutineContext] from the outer scope, but overrides
41-
* context's [Job] with [SupervisorJob].
36+
* Creates a [CoroutineScope] with [SupervisorJob] and calls the specified suspend [block] with this scope.
37+
* The provided scope inherits its [coroutineContext][CoroutineScope.coroutineContext] from the outer scope, using the
38+
* [Job] from that context as the parent for the new [SupervisorJob].
4239
* This function returns as soon as the given block and all its child coroutines are completed.
4340
*
4441
* Unlike [coroutineScope], a failure of a child does not cause this scope to fail and does not affect its other children,
4542
* so a custom policy for handling failures of its children can be implemented. See [SupervisorJob] for additional details.
46-
* A failure of the scope itself (exception thrown in the [block] or external cancellation) fails the scope with all its children,
47-
* but does not cancel parent job.
43+
*
44+
* If an exception happened in [block], then the supervisor job is failed and all its children are cancelled.
45+
* If the current coroutine was cancelled, then both the supervisor job itself and all its children are cancelled.
4846
*
4947
* The method may throw a [CancellationException] if the current job was cancelled externally,
5048
* or rethrow an exception thrown by the given [block].

‎kotlinx-coroutines-core/common/src/Yield.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@ import kotlin.coroutines.intrinsics.*
66
/**
77
* Yields the thread (or thread pool) of the current coroutine dispatcher
88
* to other coroutines on the same dispatcher to run if possible.
9-
*
10-
* This suspending function is cancellable.
11-
* If the [Job] of the current coroutine is cancelled or completed when this suspending function is invoked or while
12-
* this function is waiting for dispatch, it resumes with a [CancellationException].
13-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
14-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
9+
*
10+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while
11+
* [yield] is invoked or while waiting for dispatch, it immediately resumes with [CancellationException].
12+
* There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
13+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
1514
*
1615
* **Note**: This function always [checks for cancellation][ensureActive] even when it does not suspend.
1716
*

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

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,12 @@ public interface SendChannel<in E> {
4141
* All elements sent over the channel are delivered in first-in first-out order. The sent element
4242
* will be delivered to receivers before the close token.
4343
*
44-
* This suspending function is cancellable. If the [Job] of the current coroutine is cancelled or completed while this
45-
* function is suspended, this function immediately resumes with a [CancellationException].
46-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
47-
* suspended, it will not resume successfully. The `send` call can send the element to the channel,
48-
* but then throw [CancellationException], thus an exception should not be treated as a failure to deliver the element.
44+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
45+
* suspending function is waiting, this function immediately resumes with [CancellationException].
46+
* There is a **prompt cancellation guarantee**: even if [send] managed to send the element, but was cancelled
47+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
48+
*
49+
* Because of the prompt cancellation guarantee, an exception does not always mean a failure to deliver the element.
4950
* See "Undelivered elements" section in [Channel] documentation for details on handling undelivered elements.
5051
*
5152
* Note that this function does not check for cancellation when it is not suspended.
@@ -211,13 +212,22 @@ public interface ReceiveChannel<out E> {
211212
* If the channel was closed because of an exception, it is called a _failed_ channel and this function
212213
* will throw the original [close][SendChannel.close] cause exception.
213214
*
214-
* This suspending function is cancellable. If the [Job] of the current coroutine is cancelled or completed while this
215+
* This suspending function is cancellable. If the [Job] of the current coroutine is cancelled while this
215216
* function is suspended, this function immediately resumes with a [CancellationException].
216217
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
217218
* suspended, it will not resume successfully. The `receive` call can retrieve the element from the channel,
218219
* but then throw [CancellationException], thus failing to deliver the element.
219220
* See "Undelivered elements" section in [Channel] documentation for details on handling undelivered elements.
220221
*
222+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
223+
* suspending function is waiting, this function immediately resumes with [CancellationException].
224+
* There is a **prompt cancellation guarantee**: even if [receive] managed to retrieve the element from the channel,
225+
* but was cancelled while suspended, [CancellationException] will be thrown.
226+
* See [suspendCancellableCoroutine] for low-level details.
227+
*
228+
* Because of the prompt cancellation guarantee, some values retrieved from the channel can become lost.
229+
* See "Undelivered elements" section in [Channel] documentation for details on handling undelivered elements.
230+
*
221231
* Note that this function does not check for cancellation when it is not suspended.
222232
* Use [yield] or [CoroutineScope.isActive] to periodically check for cancellation in tight loops if needed.
223233
*
@@ -240,11 +250,13 @@ public interface ReceiveChannel<out E> {
240250
* or the close cause if the channel was closed. Closed cause may be `null` if the channel was closed normally.
241251
* The result cannot be [failed][ChannelResult.isFailure] without being [closed][ChannelResult.isClosed].
242252
*
243-
* This suspending function is cancellable. If the [Job] of the current coroutine is cancelled or completed while this
244-
* function is suspended, this function immediately resumes with a [CancellationException].
245-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
246-
* suspended, it will not resume successfully. The `receiveCatching` call can retrieve the element from the channel,
247-
* but then throw [CancellationException], thus failing to deliver the element.
253+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
254+
* suspending function is waiting, this function immediately resumes with [CancellationException].
255+
* There is a **prompt cancellation guarantee**: even if [receiveCatching] managed to retrieve the element from the
256+
* channel, but was cancelled while suspended, [CancellationException] will be thrown.
257+
* See [suspendCancellableCoroutine] for low-level details.
258+
*
259+
* Because of the prompt cancellation guarantee, some values retrieved from the channel can become lost.
248260
* See "Undelivered elements" section in [Channel] documentation for details on handling undelivered elements.
249261
*
250262
* Note that this function does not check for cancellation when it is not suspended.
@@ -561,11 +573,13 @@ public interface ChannelIterator<out E> {
561573
* This function retrieves and removes an element from this channel for the subsequent invocation
562574
* of [next].
563575
*
564-
* This suspending function is cancellable. If the [Job] of the current coroutine is cancelled or completed while this
565-
* function is suspended, this function immediately resumes with a [CancellationException].
566-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
567-
* suspended, it will not resume successfully. The `hasNext` call can retrieve the element from the channel,
568-
* but then throw [CancellationException], thus failing to deliver the element.
576+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
577+
* suspending function is waiting, this function immediately resumes with [CancellationException].
578+
* There is a **prompt cancellation guarantee**: even if [hasNext] retrieves the element from the channel during
579+
* its operation, but was cancelled while suspended, [CancellationException] will be thrown.
580+
* See [suspendCancellableCoroutine] for low-level details.
581+
*
582+
* Because of the prompt cancellation guarantee, some values retrieved from the channel can become lost.
569583
* See "Undelivered elements" section in [Channel] documentation for details on handling undelivered elements.
570584
*
571585
* Note that this function does not check for cancellation when it is not suspended.
@@ -651,21 +665,20 @@ public interface ChannelIterator<out E> {
651665
* ### Prompt cancellation guarantee
652666
*
653667
* All suspending functions with channels provide **prompt cancellation guarantee**.
654-
* If the job was cancelled while send or receive function was suspended, it will not resume successfully,
655-
* but throws a [CancellationException].
656-
* With a single-threaded [dispatcher][CoroutineDispatcher] like [Dispatchers.Main] this gives a
657-
* guarantee that if a piece code running in this thread cancels a [Job], then a coroutine running this job cannot
658-
* resume successfully and continue to run, ensuring a prompt response to its cancellation.
668+
* If the job was cancelled while send or receive function was suspended, it will not resume successfully, even if it
669+
* already changed the channel's state, but throws a [CancellationException].
670+
* With a single-threaded [dispatcher][CoroutineDispatcher] like [Dispatchers.Main], this gives a
671+
* guarantee that the coroutine promptly reacts to the cancellation of its [Job] and does not resume its execution.
659672
*
660673
* > **Prompt cancellation guarantee** for channel operations was added since `kotlinx.coroutines` version `1.4.0`
661674
* > and had replaced a channel-specific atomic-cancellation that was not consistent with other suspending functions.
662675
* > The low-level mechanics of prompt cancellation are explained in [suspendCancellableCoroutine] function.
663676
*
664677
* ### Undelivered elements
665678
*
666-
* As a result of a prompt cancellation guarantee, when a closeable resource
667-
* (like open file or a handle to another native resource) is transferred via channel from one coroutine to another
668-
* it can fail to be delivered and will be lost if either send or receive operations are cancelled in transit.
679+
* As a result of the prompt cancellation guarantee, when a closeable resource
680+
* (like open file or a handle to another native resource) is transferred via a channel from one coroutine to another,
681+
* it can fail to be delivered and will be lost if the receiving operation is cancelled in transit.
669682
*
670683
* A `Channel()` constructor function has an `onUndeliveredElement` optional parameter.
671684
* When `onUndeliveredElement` parameter is set, the corresponding function is called once for each element

‎kotlinx-coroutines-core/common/src/channels/Produce.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ public interface ProducerScope<in E> : CoroutineScope, SendChannel<E> {
2222
* Suspends the current coroutine until the channel is either [closed][SendChannel.close] or [cancelled][ReceiveChannel.cancel]
2323
* and invokes the given [block] before resuming the coroutine.
2424
*
25-
* This suspending function is cancellable.
26-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
27-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
25+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
26+
* suspending function is waiting, this function immediately resumes with [CancellationException].
27+
* There is a **prompt cancellation guarantee**: even if this function is ready to return, but was cancelled
28+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
2829
*
2930
* Note that when the producer channel is cancelled, this function resumes with a cancellation exception.
3031
* Therefore, in case of cancellation, no code after the call to this function will be executed.

‎kotlinx-coroutines-core/common/src/selects/Select.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ import kotlin.jvm.*
3838
* | [ReceiveChannel] | [receiveCatching][ReceiveChannel.receiveCatching] | [onReceiveCatching][ReceiveChannel.onReceiveCatching]
3939
* | none | [delay] | [onTimeout][SelectBuilder.onTimeout]
4040
*
41-
* This suspending function is cancellable. If the [Job] of the current coroutine is cancelled or completed while this
42-
* function is suspended, this function immediately resumes with [CancellationException].
43-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
44-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
41+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
42+
* suspending function is waiting, this function immediately resumes with [CancellationException].
43+
* There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
44+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
4545
*
4646
* Note that this function does not check for cancellation when it is not suspended.
4747
* Use [yield] or [CoroutineScope.isActive] to periodically check for cancellation in tight loops if needed.

‎kotlinx-coroutines-core/common/src/sync/Mutex.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ public interface Mutex {
4040
/**
4141
* Locks this mutex, suspending caller until the lock is acquired (in other words, while the lock is held elsewhere).
4242
*
43-
* This suspending function is cancellable. If the [Job] of the current coroutine is cancelled or completed while this
44-
* function is suspended, this function immediately resumes with [CancellationException].
45-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
46-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
43+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
44+
* suspending function is waiting, this function immediately resumes with [CancellationException].
45+
* There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
46+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
4747
* This function releases the lock if it was already acquired by this function before the [CancellationException]
4848
* was thrown.
4949
*

‎kotlinx-coroutines-core/common/src/sync/Semaphore.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ public interface Semaphore {
2828
* Acquires a permit from this semaphore, suspending until one is available.
2929
* All suspending acquirers are processed in first-in-first-out (FIFO) order.
3030
*
31-
* This suspending function is cancellable. If the [Job] of the current coroutine is cancelled or completed while this
32-
* function is suspended, this function immediately resumes with [CancellationException].
33-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
34-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
31+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
32+
* suspending function is waiting, this function immediately resumes with [CancellationException].
33+
* There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
34+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
3535
* This function releases the semaphore if it was already acquired by this function before the [CancellationException]
3636
* was thrown.
3737
*
38-
* Note, that this function does not check for cancellation when it does not suspend.
38+
* Note that this function does not check for cancellation when it does not suspend.
3939
* Use [CoroutineScope.isActive] or [CoroutineScope.ensureActive] to periodically
4040
* check for cancellation in tight loops if needed.
4141
*

‎kotlinx-coroutines-core/common/test/SupervisorTest.kt

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,12 @@ class SupervisorTest : TestBase() {
8383

8484
@Test
8585
fun testThrowingSupervisorScope() = runTest {
86+
var childJob: Job? = null
87+
var supervisorJob: Job? = null
8688
try {
8789
expect(1)
8890
supervisorScope {
89-
async {
91+
childJob = async {
9092
try {
9193
delay(Long.MAX_VALUE)
9294
} finally {
@@ -96,9 +98,13 @@ class SupervisorTest : TestBase() {
9698

9799
expect(2)
98100
yield()
101+
supervisorJob = coroutineContext.job
99102
throw TestException2()
100103
}
101104
} catch (e: Throwable) {
105+
assertIs<TestException2>(e)
106+
assertTrue(childJob!!.isCancelled)
107+
assertTrue(supervisorJob!!.isCancelled)
102108
finish(4)
103109
}
104110
}
@@ -155,6 +161,31 @@ class SupervisorTest : TestBase() {
155161
}
156162
}
157163

164+
/**
165+
* Tests that [supervisorScope] cancels all its children when the current coroutine is cancelled.
166+
*/
167+
@Test
168+
fun testSupervisorScopeExternalCancellation() = runTest {
169+
var childJob: Job? = null
170+
val job = launch {
171+
supervisorScope {
172+
childJob = launch(start = CoroutineStart.UNDISPATCHED) {
173+
try {
174+
delay(Long.MAX_VALUE)
175+
} finally {
176+
expect(2)
177+
}
178+
}
179+
}
180+
}
181+
while (childJob == null) yield()
182+
expect(1)
183+
job.cancel()
184+
assertTrue(childJob!!.isCancelled)
185+
job.join()
186+
finish(3)
187+
}
188+
158189
@Test
159190
fun testAsyncCancellation() = runTest {
160191
val parent = SupervisorJob()

‎kotlinx-coroutines-core/common/test/selects/SelectDeferredTest.kt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package kotlinx.coroutines.selects
55
import kotlinx.coroutines.testing.*
66
import kotlinx.coroutines.*
77
import kotlin.test.*
8+
import kotlin.time.Duration.Companion.seconds
89

910
class SelectDeferredTest : TestBase() {
1011
@Test
@@ -114,6 +115,23 @@ class SelectDeferredTest : TestBase() {
114115
finish(9)
115116
}
116117

118+
/**
119+
* Tests that completing a [Deferred] with an exception will cause the [select] that uses [Deferred.onAwait]
120+
* to throw the same exception.
121+
*/
122+
@Test
123+
fun testSelectFailure() = runTest {
124+
val d = CompletableDeferred<Nothing>()
125+
d.completeExceptionally(TestException())
126+
val d2 = CompletableDeferred(42)
127+
assertFailsWith<TestException> {
128+
select {
129+
d.onAwait { expectUnreached() }
130+
d2.onAwait { 4 }
131+
}
132+
}
133+
}
134+
117135
@Test
118136
fun testSelectCancel() = runTest(
119137
expected = { it is CancellationException }
@@ -167,4 +185,4 @@ class SelectDeferredTest : TestBase() {
167185
override val list: NodeList?
168186
get() = error("")
169187
}
170-
}
188+
}

‎kotlinx-coroutines-core/concurrent/src/Builders.concurrent.kt

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,21 @@ import kotlin.coroutines.*
44

55
/**
66
* Runs a new coroutine and **blocks** the current thread until its completion.
7-
* This function should not be used from a coroutine. It is designed to bridge regular blocking code
8-
* to libraries that are written in suspending style, to be used in `main` functions and in tests.
7+
*
8+
* It is designed to bridge regular blocking code to libraries that are written in suspending style, to be used in
9+
* `main` functions and in tests.
10+
*
11+
* Calling [runBlocking] from a suspend function is redundant.
12+
* For example, the following code is incorrect:
13+
* ```
14+
* suspend fun loadConfiguration() {
15+
* // DO NOT DO THIS:
16+
* val data = runBlocking { // <- redundant and blocks the thread, do not do that
17+
* fetchConfigurationData() // suspending function
18+
* }
19+
* ```
20+
*
21+
* Here, instead of releasing the thread on which `loadConfiguration` runs if `fetchConfigurationData` suspends, it will
22+
* block, potentially leading to thread starvation issues.
923
*/
10-
public expect fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T
24+
public expect fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T

‎kotlinx-coroutines-core/jdk8/src/future/Future.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public fun <T> CompletionStage<T>.asDeferred(): Deferred<T> {
146146
* Awaits for completion of [CompletionStage] without blocking a thread.
147147
*
148148
* This suspending function is cancellable.
149-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
149+
* If the [Job] of the current coroutine is cancelled while this suspending function is waiting, this function
150150
* stops waiting for the completion stage and immediately resumes with [CancellationException][kotlinx.coroutines.CancellationException].
151151
*
152152
* This method is intended to be used with one-shot futures, so on coroutine cancellation the [CompletableFuture] that

‎kotlinx-coroutines-core/js/src/Promise.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,10 @@ public fun <T> Promise<T>.asDeferred(): Deferred<T> {
5555
/**
5656
* Awaits for completion of the promise without blocking.
5757
*
58-
* This suspending function is cancellable.
59-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
60-
* stops waiting for the promise and immediately resumes with [CancellationException].
61-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
62-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
58+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
59+
* suspending function is waiting on the promise, this function immediately resumes with [CancellationException].
60+
* There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
61+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
6362
*/
6463
public suspend fun <T> Promise<T>.await(): T = suspendCancellableCoroutine { cont: CancellableContinuation<T> ->
6564
this@await.then(

‎kotlinx-coroutines-core/jvm/src/Builders.kt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,22 @@ import kotlin.coroutines.*
1010

1111
/**
1212
* Runs a new coroutine and **blocks** the current thread _interruptibly_ until its completion.
13-
* This function should not be used from a coroutine. It is designed to bridge regular blocking code
14-
* to libraries that are written in suspending style, to be used in `main` functions and in tests.
13+
*
14+
* It is designed to bridge regular blocking code to libraries that are written in suspending style, to be used in
15+
* `main` functions and in tests.
16+
*
17+
* Calling [runBlocking] from a suspend function is redundant.
18+
* For example, the following code is incorrect:
19+
* ```
20+
* suspend fun loadConfiguration() {
21+
* // DO NOT DO THIS:
22+
* val data = runBlocking { // <- redundant and blocks the thread, do not do that
23+
* fetchConfigurationData() // suspending function
24+
* }
25+
* ```
26+
*
27+
* Here, instead of releasing the thread on which `loadConfiguration` runs if `fetchConfigurationData` suspends, it will
28+
* block, potentially leading to thread starvation issues.
1529
*
1630
* The default [CoroutineDispatcher] for this builder is an internal implementation of event loop that processes continuations
1731
* in this blocked thread until the completion of this coroutine.

‎kotlinx-coroutines-core/native/src/Builders.kt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,22 @@ import kotlin.native.concurrent.*
88

99
/**
1010
* Runs new coroutine and **blocks** current thread _interruptibly_ until its completion.
11-
* This function should not be used from coroutine. It is designed to bridge regular blocking code
12-
* to libraries that are written in suspending style, to be used in `main` functions and in tests.
11+
*
12+
* It is designed to bridge regular blocking code to libraries that are written in suspending style, to be used in
13+
* `main` functions and in tests.
14+
*
15+
* Calling [runBlocking] from a suspend function is redundant.
16+
* For example, the following code is incorrect:
17+
* ```
18+
* suspend fun loadConfiguration() {
19+
* // DO NOT DO THIS:
20+
* val data = runBlocking { // <- redundant and blocks the thread, do not do that
21+
* fetchConfigurationData() // suspending function
22+
* }
23+
* ```
24+
*
25+
* Here, instead of releasing the thread on which `loadConfiguration` runs if `fetchConfigurationData` suspends, it will
26+
* block, potentially leading to thread starvation issues.
1327
*
1428
* The default [CoroutineDispatcher] for this builder in an implementation of [EventLoop] that processes continuations
1529
* in this blocked thread until the completion of this coroutine.

‎kotlinx-coroutines-core/wasmJs/src/Promise.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,10 @@ public fun <T> Promise<JsAny?>.asDeferred(): Deferred<T> {
6666
/**
6767
* Awaits for completion of the promise without blocking.
6868
*
69-
* This suspending function is cancellable.
70-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
71-
* stops waiting for the promise and immediately resumes with [CancellationException].
72-
* There is a **prompt cancellation guarantee**. If the job was cancelled while this function was
73-
* suspended, it will not resume successfully. See [suspendCancellableCoroutine] documentation for low-level details.
69+
* This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
70+
* suspending function is waiting on the promise, this function immediately resumes with [CancellationException].
71+
* There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
72+
* while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
7473
*/
7574
@Suppress("UNCHECKED_CAST")
7675
public suspend fun <T> Promise<JsAny?>.await(): T = suspendCancellableCoroutine { cont: CancellableContinuation<T> ->

‎reactive/kotlinx-coroutines-jdk9/src/Await.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import kotlinx.coroutines.reactive.*
1010
* the publisher has produced an error, throws the corresponding exception.
1111
*
1212
* This suspending function is cancellable.
13-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
13+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
1414
* function immediately cancels its [Flow.Subscription] and resumes with [CancellationException].
1515
*
1616
* @throws NoSuchElementException if the publisher does not emit any value
@@ -24,7 +24,7 @@ public suspend fun <T> Flow.Publisher<T>.awaitFirst(): T =
2424
* exception.
2525
*
2626
* This suspending function is cancellable.
27-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
27+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
2828
* function immediately cancels its [Flow.Subscription] and resumes with [CancellationException].
2929
*/
3030
public suspend fun <T> Flow.Publisher<T>.awaitFirstOrDefault(default: T): T =
@@ -35,7 +35,7 @@ public suspend fun <T> Flow.Publisher<T>.awaitFirstOrDefault(default: T): T =
3535
* and returns the resulting value, or, if this publisher has produced an error, throws the corresponding exception.
3636
*
3737
* This suspending function is cancellable.
38-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
38+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
3939
* function immediately cancels its [Flow.Subscription] and resumes with [CancellationException].
4040
*/
4141
public suspend fun <T> Flow.Publisher<T>.awaitFirstOrNull(): T? =
@@ -47,7 +47,7 @@ public suspend fun <T> Flow.Publisher<T>.awaitFirstOrNull(): T? =
4747
* corresponding exception.
4848
*
4949
* This suspending function is cancellable.
50-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
50+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
5151
* function immediately cancels its [Flow.Subscription] and resumes with [CancellationException].
5252
*/
5353
public suspend fun <T> Flow.Publisher<T>.awaitFirstOrElse(defaultValue: () -> T): T =
@@ -58,7 +58,7 @@ public suspend fun <T> Flow.Publisher<T>.awaitFirstOrElse(defaultValue: () -> T)
5858
* returns the resulting value, or, if this publisher has produced an error, throws the corresponding exception.
5959
*
6060
* This suspending function is cancellable.
61-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
61+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
6262
* function immediately cancels its [Flow.Subscription] and resumes with [CancellationException].
6363
*
6464
* @throws NoSuchElementException if the publisher does not emit any value
@@ -71,7 +71,7 @@ public suspend fun <T> Flow.Publisher<T>.awaitLast(): T =
7171
* if this publisher has produced an error, throws the corresponding exception.
7272
*
7373
* This suspending function is cancellable.
74-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
74+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
7575
* function immediately cancels its [Flow.Subscription] and resumes with [CancellationException].
7676
*
7777
* @throws NoSuchElementException if the publisher does not emit any value

‎reactive/kotlinx-coroutines-reactive/src/Await.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import kotlin.coroutines.*
1212
* the publisher has produced an error, throws the corresponding exception.
1313
*
1414
* This suspending function is cancellable.
15-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
15+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
1616
* function immediately cancels its [Subscription] and resumes with [CancellationException].
1717
*
1818
* @throws NoSuchElementException if the publisher does not emit any value
@@ -25,7 +25,7 @@ public suspend fun <T> Publisher<T>.awaitFirst(): T = awaitOne(Mode.FIRST)
2525
* exception.
2626
*
2727
* This suspending function is cancellable.
28-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
28+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
2929
* function immediately cancels its [Subscription] and resumes with [CancellationException].
3030
*/
3131
public suspend fun <T> Publisher<T>.awaitFirstOrDefault(default: T): T = awaitOne(Mode.FIRST_OR_DEFAULT, default)
@@ -35,7 +35,7 @@ public suspend fun <T> Publisher<T>.awaitFirstOrDefault(default: T): T = awaitOn
3535
* and returns the resulting value, or, if this publisher has produced an error, throws the corresponding exception.
3636
*
3737
* This suspending function is cancellable.
38-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
38+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
3939
* function immediately cancels its [Subscription] and resumes with [CancellationException].
4040
*/
4141
public suspend fun <T> Publisher<T>.awaitFirstOrNull(): T? = awaitOne(Mode.FIRST_OR_DEFAULT)
@@ -46,7 +46,7 @@ public suspend fun <T> Publisher<T>.awaitFirstOrNull(): T? = awaitOne(Mode.FIRST
4646
* corresponding exception.
4747
*
4848
* This suspending function is cancellable.
49-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
49+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
5050
* function immediately cancels its [Subscription] and resumes with [CancellationException].
5151
*/
5252
public suspend fun <T> Publisher<T>.awaitFirstOrElse(defaultValue: () -> T): T = awaitOne(Mode.FIRST_OR_DEFAULT) ?: defaultValue()
@@ -56,7 +56,7 @@ public suspend fun <T> Publisher<T>.awaitFirstOrElse(defaultValue: () -> T): T =
5656
* returns the resulting value, or, if this publisher has produced an error, throws the corresponding exception.
5757
*
5858
* This suspending function is cancellable.
59-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
59+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
6060
* function immediately cancels its [Subscription] and resumes with [CancellationException].
6161
*
6262
* @throws NoSuchElementException if the publisher does not emit any value
@@ -68,7 +68,7 @@ public suspend fun <T> Publisher<T>.awaitLast(): T = awaitOne(Mode.LAST)
6868
* if this publisher has produced an error, throws the corresponding exception.
6969
*
7070
* This suspending function is cancellable.
71-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
71+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
7272
* function immediately cancels its [Subscription] and resumes with [CancellationException].
7373
*
7474
* @throws NoSuchElementException if the publisher does not emit any value
@@ -82,7 +82,7 @@ public suspend fun <T> Publisher<T>.awaitSingle(): T = awaitOne(Mode.SINGLE)
8282
* corresponding exception.
8383
*
8484
* This suspending function is cancellable.
85-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
85+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
8686
* function immediately cancels its [Subscription] and resumes with [CancellationException].
8787
*
8888
* ### Deprecation
@@ -112,7 +112,7 @@ public suspend fun <T> Publisher<T>.awaitSingleOrDefault(default: T): T = awaitO
112112
* produced by the publisher, `null` is returned.
113113
*
114114
* This suspending function is cancellable.
115-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
115+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
116116
* function immediately cancels its [Subscription] and resumes with [CancellationException].
117117
*
118118
* ### Deprecation
@@ -142,7 +142,7 @@ public suspend fun <T> Publisher<T>.awaitSingleOrNull(): T? = awaitOne(Mode.SING
142142
* corresponding exception.
143143
*
144144
* This suspending function is cancellable.
145-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
145+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
146146
* function immediately cancels its [Subscription] and resumes with [CancellationException].
147147
*
148148
* ### Deprecation

‎reactive/kotlinx-coroutines-reactor/src/Mono.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public fun <T> mono(
3636
* `null` is returned.
3737
*
3838
* This suspending function is cancellable.
39-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
39+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
4040
* function immediately cancels its [Subscription] and resumes with [CancellationException].
4141
*/
4242
public suspend fun <T> Mono<T>.awaitSingleOrNull(): T? = suspendCancellableCoroutine { cont ->
@@ -68,7 +68,7 @@ public suspend fun <T> Mono<T>.awaitSingleOrNull(): T? = suspendCancellableCorou
6868
* if this Mono has produced an error, throws the corresponding exception.
6969
*
7070
* This suspending function is cancellable.
71-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
71+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
7272
* function immediately cancels its [Subscription] and resumes with [CancellationException].
7373
*
7474
* @throws NoSuchElementException if the Mono does not emit any value

‎reactive/kotlinx-coroutines-rx2/src/RxAwait.kt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import kotlin.coroutines.*
1414
* Awaits for completion of this completable without blocking the thread.
1515
* Returns `Unit`, or throws the corresponding exception if this completable produces an error.
1616
*
17-
* This suspending function is cancellable. If the [Job] of the invoking coroutine is cancelled or completed while this
17+
* This suspending function is cancellable. If the [Job] of the invoking coroutine is cancelled while this
1818
* suspending function is suspended, this function immediately resumes with [CancellationException] and disposes of its
1919
* subscription.
2020
*/
@@ -42,7 +42,7 @@ public suspend fun CompletableSource.await(): Unit = suspendCancellableCoroutine
4242
* [MaybeSource] produces an error.
4343
*
4444
* This suspending function is cancellable.
45-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this
45+
* If the [Job] of the current coroutine is cancelled while this suspending function is waiting, this
4646
* function immediately resumes with [CancellationException] and disposes of its subscription.
4747
*/
4848
public suspend fun <T> MaybeSource<T>.awaitSingleOrNull(): T? = suspendCancellableCoroutine { cont ->
@@ -70,7 +70,7 @@ public suspend fun <T> MaybeSource<T>.awaitSingleOrNull(): T? = suspendCancellab
7070
* Returns the resulting value, or throws if either no value is produced or this [MaybeSource] produces an error.
7171
*
7272
* This suspending function is cancellable.
73-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this
73+
* If the [Job] of the current coroutine is cancelled while this suspending function is waiting, this
7474
* function immediately resumes with [CancellationException] and disposes of its subscription.
7575
*
7676
* @throws NoSuchElementException if no elements were produced by this [MaybeSource].
@@ -83,7 +83,7 @@ public suspend fun <T> MaybeSource<T>.awaitSingle(): T = awaitSingleOrNull() ?:
8383
* maybe had produced error.
8484
*
8585
* This suspending function is cancellable.
86-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
86+
* If the [Job] of the current coroutine is cancelled while this suspending function is waiting, this function
8787
* immediately resumes with [CancellationException].
8888
*
8989
* ### Deprecation
@@ -105,7 +105,7 @@ public suspend fun <T> MaybeSource<T>.await(): T? = awaitSingleOrNull()
105105
* maybe had produced error.
106106
*
107107
* This suspending function is cancellable.
108-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
108+
* If the [Job] of the current coroutine is cancelled while this suspending function is waiting, this function
109109
* immediately resumes with [CancellationException].
110110
*
111111
* ### Deprecation
@@ -128,7 +128,7 @@ public suspend fun <T> MaybeSource<T>.awaitOrDefault(default: T): T = awaitSingl
128128
* Returns the resulting value, or throws the corresponding exception if this response produces an error.
129129
*
130130
* This suspending function is cancellable.
131-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
131+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
132132
* function immediately disposes of its subscription and resumes with [CancellationException].
133133
*/
134134
public suspend fun <T> SingleSource<T>.await(): T = suspendCancellableCoroutine { cont ->
@@ -154,7 +154,7 @@ public suspend fun <T> SingleSource<T>.await(): T = suspendCancellableCoroutine
154154
* if the observable has produced an error, throws the corresponding exception.
155155
*
156156
* This suspending function is cancellable.
157-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
157+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
158158
* function immediately disposes of its subscription and resumes with [CancellationException].
159159
*
160160
* @throws NoSuchElementException if the observable does not emit any value
@@ -167,7 +167,7 @@ public suspend fun <T> ObservableSource<T>.awaitFirst(): T = awaitOne(Mode.FIRST
167167
* corresponding exception.
168168
*
169169
* This suspending function is cancellable.
170-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
170+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
171171
* function immediately disposes of its subscription and resumes with [CancellationException].
172172
*/
173173
public suspend fun <T> ObservableSource<T>.awaitFirstOrDefault(default: T): T = awaitOne(Mode.FIRST_OR_DEFAULT, default)
@@ -178,7 +178,7 @@ public suspend fun <T> ObservableSource<T>.awaitFirstOrDefault(default: T): T =
178178
* exception.
179179
*
180180
* This suspending function is cancellable.
181-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
181+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
182182
* function immediately disposes of its subscription and resumes with [CancellationException].
183183
*/
184184
public suspend fun <T> ObservableSource<T>.awaitFirstOrNull(): T? = awaitOne(Mode.FIRST_OR_DEFAULT)
@@ -189,7 +189,7 @@ public suspend fun <T> ObservableSource<T>.awaitFirstOrNull(): T? = awaitOne(Mod
189189
* the corresponding exception.
190190
*
191191
* This suspending function is cancellable.
192-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
192+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
193193
* function immediately disposes of its subscription and resumes with [CancellationException].
194194
*/
195195
public suspend fun <T> ObservableSource<T>.awaitFirstOrElse(defaultValue: () -> T): T =
@@ -200,7 +200,7 @@ public suspend fun <T> ObservableSource<T>.awaitFirstOrElse(defaultValue: () ->
200200
* returns the resulting value, or, if this observable has produced an error, throws the corresponding exception.
201201
*
202202
* This suspending function is cancellable.
203-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
203+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
204204
* function immediately disposes of its subscription and resumes with [CancellationException].
205205
*
206206
* @throws NoSuchElementException if the observable does not emit any value
@@ -212,7 +212,7 @@ public suspend fun <T> ObservableSource<T>.awaitLast(): T = awaitOne(Mode.LAST)
212212
* if this observable has produced an error, throws the corresponding exception.
213213
*
214214
* This suspending function is cancellable.
215-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
215+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
216216
* function immediately disposes of its subscription and resumes with [CancellationException].
217217
*
218218
* @throws NoSuchElementException if the observable does not emit any value

‎reactive/kotlinx-coroutines-rx3/src/RxAwait.kt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import kotlin.coroutines.*
1414
* Awaits for completion of this completable without blocking the thread.
1515
* Returns `Unit`, or throws the corresponding exception if this completable produces an error.
1616
*
17-
* This suspending function is cancellable. If the [Job] of the invoking coroutine is cancelled or completed while this
17+
* This suspending function is cancellable. If the [Job] of the invoking coroutine is cancelled while this
1818
* suspending function is suspended, this function immediately resumes with [CancellationException] and disposes of its
1919
* subscription.
2020
*/
@@ -34,7 +34,7 @@ public suspend fun CompletableSource.await(): Unit = suspendCancellableCoroutine
3434
* [MaybeSource] produces an error.
3535
*
3636
* This suspending function is cancellable.
37-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this
37+
* If the [Job] of the current coroutine is cancelled while this suspending function is waiting, this
3838
* function immediately resumes with [CancellationException] and disposes of its subscription.
3939
*/
4040
public suspend fun <T> MaybeSource<T & Any>.awaitSingleOrNull(): T? = suspendCancellableCoroutine { cont ->
@@ -51,7 +51,7 @@ public suspend fun <T> MaybeSource<T & Any>.awaitSingleOrNull(): T? = suspendCan
5151
* Returns the resulting value, or throws if either no value is produced or this [MaybeSource] produces an error.
5252
*
5353
* This suspending function is cancellable.
54-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this
54+
* If the [Job] of the current coroutine is cancelled while this suspending function is waiting, this
5555
* function immediately resumes with [CancellationException] and disposes of its subscription.
5656
*
5757
* @throws NoSuchElementException if no elements were produced by this [MaybeSource].
@@ -64,7 +64,7 @@ public suspend fun <T> MaybeSource<T & Any>.awaitSingle(): T = awaitSingleOrNull
6464
* maybe had produced error.
6565
*
6666
* This suspending function is cancellable.
67-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
67+
* If the [Job] of the current coroutine is cancelled while this suspending function is waiting, this function
6868
* immediately resumes with [CancellationException].
6969
*
7070
* ### Deprecation
@@ -87,7 +87,7 @@ public suspend fun <T> MaybeSource<T & Any>.await(): T? = awaitSingleOrNull()
8787
* maybe had produced error.
8888
*
8989
* This suspending function is cancellable.
90-
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
90+
* If the [Job] of the current coroutine is cancelled while this suspending function is waiting, this function
9191
* immediately resumes with [CancellationException].
9292
*
9393
* ### Deprecation
@@ -111,7 +111,7 @@ public suspend fun <T> MaybeSource<T & Any>.awaitOrDefault(default: T): T = awai
111111
* Returns the resulting value, or throws the corresponding exception if this response produces an error.
112112
*
113113
* This suspending function is cancellable.
114-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
114+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
115115
* function immediately disposes of its subscription and resumes with [CancellationException].
116116
*/
117117
public suspend fun <T> SingleSource<T & Any>.await(): T = suspendCancellableCoroutine { cont ->
@@ -129,7 +129,7 @@ public suspend fun <T> SingleSource<T & Any>.await(): T = suspendCancellableCoro
129129
* if the observable has produced an error, throws the corresponding exception.
130130
*
131131
* This suspending function is cancellable.
132-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
132+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
133133
* function immediately disposes of its subscription and resumes with [CancellationException].
134134
*
135135
* @throws NoSuchElementException if the observable does not emit any value
@@ -143,7 +143,7 @@ public suspend fun <T> ObservableSource<T & Any>.awaitFirst(): T = awaitOne(Mode
143143
* corresponding exception.
144144
*
145145
* This suspending function is cancellable.
146-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
146+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
147147
* function immediately disposes of its subscription and resumes with [CancellationException].
148148
*/
149149
@Suppress("UNCHECKED_CAST")
@@ -156,7 +156,7 @@ public suspend fun <T> ObservableSource<T & Any>.awaitFirstOrDefault(default: T)
156156
* exception.
157157
*
158158
* This suspending function is cancellable.
159-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
159+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
160160
* function immediately disposes of its subscription and resumes with [CancellationException].
161161
*/
162162
public suspend fun <T> ObservableSource<T & Any>.awaitFirstOrNull(): T? = awaitOne(Mode.FIRST_OR_DEFAULT)
@@ -167,7 +167,7 @@ public suspend fun <T> ObservableSource<T & Any>.awaitFirstOrNull(): T? = awaitO
167167
* the corresponding exception.
168168
*
169169
* This suspending function is cancellable.
170-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
170+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
171171
* function immediately disposes of its subscription and resumes with [CancellationException].
172172
*/
173173
public suspend fun <T> ObservableSource<T & Any>.awaitFirstOrElse(defaultValue: () -> T): T =
@@ -178,7 +178,7 @@ public suspend fun <T> ObservableSource<T & Any>.awaitFirstOrElse(defaultValue:
178178
* returns the resulting value, or, if this observable has produced an error, throws the corresponding exception.
179179
*
180180
* This suspending function is cancellable.
181-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
181+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
182182
* function immediately disposes of its subscription and resumes with [CancellationException].
183183
*
184184
* @throws NoSuchElementException if the observable does not emit any value
@@ -191,7 +191,7 @@ public suspend fun <T> ObservableSource<T & Any>.awaitLast(): T = awaitOne(Mode.
191191
* if this observable has produced an error, throws the corresponding exception.
192192
*
193193
* This suspending function is cancellable.
194-
* If the [Job] of the current coroutine is cancelled or completed while the suspending function is waiting, this
194+
* If the [Job] of the current coroutine is cancelled while the suspending function is waiting, this
195195
* function immediately disposes of its subscription and resumes with [CancellationException].
196196
*
197197
* @throws NoSuchElementException if the observable does not emit any value

0 commit comments

Comments
 (0)
Please sign in to comment.