Skip to content

Commit 5531a6e

Browse files
authored
Promote CoroutineStart.UNDISPATCHED to non experimental API (#2505)
Fixes #1393
1 parent d37b834 commit 5531a6e

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

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

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
2+
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
33
*/
44
package kotlinx.coroutines
55

@@ -58,8 +58,8 @@ public enum class CoroutineStart {
5858
ATOMIC,
5959

6060
/**
61-
* Immediately executes the coroutine until its first suspension point _in the current thread_ as if the
62-
* coroutine was started using [Dispatchers.Unconfined]. However, when the coroutine is resumed from suspension
61+
* Immediately executes the coroutine until its first suspension point _in the current thread_ similarly to
62+
* the coroutine being started using [Dispatchers.Unconfined]. However, when the coroutine is resumed from suspension
6363
* it is dispatched according to the [CoroutineDispatcher] in its context.
6464
*
6565
* This is similar to [ATOMIC] in the sense that coroutine starts executing even if it was already cancelled,
@@ -68,9 +68,11 @@ public enum class CoroutineStart {
6868
* Cancellability of coroutine at suspension points depends on the particular implementation details of
6969
* suspending functions as in [DEFAULT].
7070
*
71-
* **Note: This is an experimental api.** Execution semantics of coroutines may change in the future when this mode is used.
71+
* ### Unconfined event loop
72+
*
73+
* Unlike [Dispatchers.Unconfined] and [MainCoroutineDispatcher.immediate], nested undispatched coroutines do not form
74+
* an event loop that otherwise prevents potential stack overflow in case of unlimited nesting.
7275
*/
73-
@ExperimentalCoroutinesApi // Since 1.0.0, no ETA on stability
7476
UNDISPATCHED;
7577

7678
/**

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

+34-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
2+
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

55
package kotlinx.coroutines
@@ -31,6 +31,38 @@ class AtomicCancellationCommonTest : TestBase() {
3131
expect(3)
3232
}
3333

34+
@Test
35+
fun testUndispatchedLaunch() = runTest {
36+
expect(1)
37+
assertFailsWith<CancellationException> {
38+
withContext(Job()) {
39+
cancel()
40+
launch(start = CoroutineStart.UNDISPATCHED) {
41+
expect(2)
42+
yield()
43+
expectUnreached()
44+
}
45+
}
46+
}
47+
finish(3)
48+
}
49+
50+
@Test
51+
fun testUndispatchedLaunchWithUnconfinedContext() = runTest {
52+
expect(1)
53+
assertFailsWith<CancellationException> {
54+
withContext(Dispatchers.Unconfined + Job()) {
55+
cancel()
56+
launch(start = CoroutineStart.UNDISPATCHED) {
57+
expect(2)
58+
yield()
59+
expectUnreached()
60+
}
61+
}
62+
}
63+
finish(3)
64+
}
65+
3466
@Test
3567
fun testDeferredAwaitCancellable() = runTest {
3668
expect(1)
@@ -122,4 +154,4 @@ class AtomicCancellationCommonTest : TestBase() {
122154
yield() // now yield
123155
finish(4)
124156
}
125-
}
157+
}

0 commit comments

Comments
 (0)