Skip to content

Commit ac91fe2

Browse files
committed
Introduce first version of Dispatchers.IO for K/N
* Emulate expect declaration refinement via extension property as the only way to do it in a backwards-compatible manner: in the current model it is impossible to have common 'expect' Dispatchers declaration, then refined 'concurrent' Dispatchers declaration with 'expect val IO' and then JVM declaration with JVM-specific members. Current solutions seems to be the less intrusive one * Elasticity is not supported as K/N Workers API lacks capability to gracefully shutdown workers, meaning that for any unlimited underlying pool, memory consumption is only going to grow in an unbound manner Fixes #3205
1 parent 0eb94dd commit ac91fe2

File tree

6 files changed

+48
-4
lines changed

6 files changed

+48
-4
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ public final class kotlinx/coroutines/Dispatchers {
302302

303303
public final class kotlinx/coroutines/DispatchersKt {
304304
public static final field IO_PARALLELISM_PROPERTY_NAME Ljava/lang/String;
305+
public static final synthetic fun getIO (Lkotlinx/coroutines/Dispatchers;)Lkotlinx/coroutines/CoroutineDispatcher;
305306
}
306307

307308
public abstract interface class kotlinx/coroutines/DisposableHandle {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import kotlin.coroutines.*
1212
public expect object Dispatchers {
1313
/**
1414
* The default [CoroutineDispatcher] that is used by all standard builders like
15-
* [launch][CoroutineScope.launch], [async][CoroutineScope.async], etc
15+
* [launch][CoroutineScope.launch], [async][CoroutineScope.async], etc.
1616
* if neither a dispatcher nor any other [ContinuationInterceptor] is specified in their context.
1717
*
1818
* It is backed by a shared pool of threads on JVM. By default, the maximum number of threads used
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright 2016-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.coroutines
6+
7+
/**
8+
* The [CoroutineDispatcher] that is designed for offloading blocking IO tasks to a shared pool of threads.
9+
* Additional threads in this pool are created on demand.
10+
*
11+
* By default, the pool is backed by `64` standalone threads, for the additional details
12+
* such as elasticity, dynamic sizing and interaction with [CoroutineDispatcher.limitedParallelism],
13+
* please refer to the documentation of `Dispatchers.IO` on specific platform.
14+
*/
15+
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
16+
public expect val Dispatchers.IO: CoroutineDispatcher
17+
18+

kotlinx-coroutines-core/concurrent/test/DefaultDispatcherConcurrencyTest.kt renamed to kotlinx-coroutines-core/concurrent/test/DefaultDispatchersConcurrencyTest.kt

+4
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@ package kotlinx.coroutines
66
class DefaultDispatcherConcurrencyTest : AbstractDispatcherConcurrencyTest() {
77
override val dispatcher: CoroutineDispatcher = Dispatchers.Default
88
}
9+
10+
class IoDispatcherConcurrencyTest : AbstractDispatcherConcurrencyTest() {
11+
override val dispatcher: CoroutineDispatcher = Dispatchers.IO
12+
}

kotlinx-coroutines-core/jvm/src/Dispatchers.kt

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

5-
@file:Suppress("unused")
6-
75
package kotlinx.coroutines
86

97
import kotlinx.coroutines.internal.*
@@ -161,3 +159,13 @@ public actual object Dispatchers {
161159
DefaultScheduler.shutdown()
162160
}
163161
}
162+
163+
/**
164+
* `actual` counterpart of the corresponding `expect` declaration.
165+
* Should never be used directly from JVM sources, all accesses
166+
* to `Dispatchers.IO` should be resolved to the corresponding member of [Dispatchers] object.
167+
* @suppress
168+
*/
169+
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
170+
@Deprecated(message = "Should not be used directly", level = DeprecationLevel.HIDDEN)
171+
public actual val Dispatchers.IO: CoroutineDispatcher get() = Dispatchers.IO

kotlinx-coroutines-core/native/src/Dispatchers.kt

+13
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ public actual object Dispatchers {
1919
internal fun injectMain(dispatcher: MainCoroutineDispatcher) {
2020
injectedMainDispatcher = dispatcher
2121
}
22+
23+
internal val IO: CoroutineDispatcher = newFixedThreadPoolContext(64, "Dispatchers.IO")
2224
}
2325

26+
/**
27+
* The [CoroutineDispatcher] that is designed for offloading blocking IO tasks to a shared pool of threads.
28+
* Additional threads in this pool are created on demand.
29+
*
30+
* On Native platforms it is backed by a standalone [newFixedThreadPoolContext] with `64` worker threads in it.
31+
* **NB**: this dispatcher **does not** share the same elasticity behaviour for [CoroutineDispatcher.limitedParallelism]
32+
* as `Dispatchers.IO` on JVM.
33+
*/
34+
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
35+
public actual val Dispatchers.IO: CoroutineDispatcher get() = IO
36+
2437
internal expect fun createMainDispatcher(default: CoroutineDispatcher): MainCoroutineDispatcher

0 commit comments

Comments
 (0)