Skip to content

Commit b286646

Browse files
authored
Remove various obsolete code (#4196)
Removed some code that's no longer relevant: * Backward compatibility for Ktor 1.0.0, * Some code that was more complex than needed to support that, * A JDK 6 workaround, * Other small things.
1 parent f0bdf00 commit b286646

18 files changed

+81
-388
lines changed

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

-17
Original file line numberDiff line numberDiff line change
@@ -1258,23 +1258,6 @@ public final class kotlinx/coroutines/intrinsics/CancellableKt {
12581258
public static final fun startCoroutineCancellable (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)V
12591259
}
12601260

1261-
public class kotlinx/coroutines/scheduling/ExperimentalCoroutineDispatcher : kotlinx/coroutines/ExecutorCoroutineDispatcher {
1262-
public synthetic fun <init> (II)V
1263-
public synthetic fun <init> (IIILkotlin/jvm/internal/DefaultConstructorMarker;)V
1264-
public fun <init> (IIJLjava/lang/String;)V
1265-
public synthetic fun <init> (IIJLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
1266-
public fun <init> (IILjava/lang/String;)V
1267-
public synthetic fun <init> (IILjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
1268-
public final fun blocking (I)Lkotlinx/coroutines/CoroutineDispatcher;
1269-
public static synthetic fun blocking$default (Lkotlinx/coroutines/scheduling/ExperimentalCoroutineDispatcher;IILjava/lang/Object;)Lkotlinx/coroutines/CoroutineDispatcher;
1270-
public fun close ()V
1271-
public fun dispatch (Lkotlin/coroutines/CoroutineContext;Ljava/lang/Runnable;)V
1272-
public fun dispatchYield (Lkotlin/coroutines/CoroutineContext;Ljava/lang/Runnable;)V
1273-
public fun getExecutor ()Ljava/util/concurrent/Executor;
1274-
public final fun limited (I)Lkotlinx/coroutines/CoroutineDispatcher;
1275-
public fun toString ()Ljava/lang/String;
1276-
}
1277-
12781261
public final class kotlinx/coroutines/selects/OnTimeoutKt {
12791262
public static final fun onTimeout (Lkotlinx/coroutines/selects/SelectBuilder;JLkotlin/jvm/functions/Function1;)V
12801263
public static final fun onTimeout-8Mi8wO0 (Lkotlinx/coroutines/selects/SelectBuilder;JLkotlin/jvm/functions/Function1;)V

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

+13-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package kotlinx.coroutines
22

3+
/**
4+
* A [Runnable] that's especially optimized for running in [Dispatchers.Default] on the JVM.
5+
*
6+
* Replacing a [SchedulerTask] with a [Runnable] should not lead to any change in observable behavior.
7+
*
8+
* An arbitrary [Runnable], once it is dispatched by [Dispatchers.Default], gets wrapped into a class that
9+
* stores the submission time, the execution context, etc.
10+
* For [Runnable] instances that we know are only going to be executed in dispatch procedures, we can avoid the
11+
* overhead of separately allocating a wrapper, and instead have the [Runnable] contain the required fields
12+
* on construction.
13+
*
14+
* When running outside the standard dispatchers, these new fields are just dead weight.
15+
*/
316
internal expect abstract class SchedulerTask internal constructor() : Runnable
4-
5-
internal expect interface SchedulerTaskContext
6-
7-
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
8-
internal expect val SchedulerTask.taskContext: SchedulerTaskContext
9-
10-
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
11-
internal expect inline fun SchedulerTaskContext.afterTask()

kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt

+4-12
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ internal abstract class DispatchedTask<in T> internal constructor(
7676

7777
final override fun run() {
7878
assert { resumeMode != MODE_UNINITIALIZED } // should have been set before dispatching
79-
val taskContext = this.taskContext
8079
var fatalException: Throwable? = null
8180
try {
8281
val delegate = delegate as DispatchedContinuation<T>
@@ -107,8 +106,7 @@ internal abstract class DispatchedTask<in T> internal constructor(
107106
// This instead of runCatching to have nicer stacktrace and debug experience
108107
fatalException = e
109108
} finally {
110-
val result = runCatching { taskContext.afterTask() }
111-
handleFatalException(fatalException, result.exceptionOrNull())
109+
fatalException?.let { handleFatalException(it) }
112110
}
113111
}
114112

@@ -130,15 +128,9 @@ internal abstract class DispatchedTask<in T> internal constructor(
130128
* Fatal exception handling can be intercepted with [CoroutineExceptionHandler] element in the context of
131129
* a failed coroutine, but such exceptions should be reported anyway.
132130
*/
133-
internal fun handleFatalException(exception: Throwable?, finallyException: Throwable?) {
134-
if (exception === null && finallyException === null) return
135-
if (exception !== null && finallyException !== null) {
136-
exception.addSuppressed(finallyException)
137-
}
138-
139-
val cause = exception ?: finallyException
131+
internal fun handleFatalException(exception: Throwable) {
140132
val reason = CoroutinesInternalError("Fatal exception in coroutines machinery for $this. " +
141-
"Please read KDoc to 'handleFatalException' method and report this incident to maintainers", cause!!)
133+
"Please read KDoc to 'handleFatalException' method and report this incident to maintainers", exception)
142134
handleCoroutineException(this.delegate.context, reason)
143135
}
144136
}
@@ -203,7 +195,7 @@ internal inline fun DispatchedTask<*>.runUnconfinedEventLoop(
203195
* This exception doesn't happen normally, only if we have a bug in implementation.
204196
* Report it as a fatal exception.
205197
*/
206-
handleFatalException(e, null)
198+
handleFatalException(e)
207199
} finally {
208200
eventLoop.decrementUseCount(unconfined = true)
209201
}

kotlinx-coroutines-core/common/src/internal/LocalAtomics.common.kt

+2-4
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@ package kotlinx.coroutines.internal
55
* where atomicfu doesn't support its tranformations.
66
*
77
* Have `Local` prefix to avoid AFU clashes during star-imports
8+
*
9+
* TODO: remove after https://youtrack.jetbrains.com/issue/KT-62423/
810
*/
911
internal expect class LocalAtomicInt(value: Int) {
1012
fun get(): Int
1113
fun set(value: Int)
1214
fun decrementAndGet(): Int
1315
}
14-
15-
internal inline var LocalAtomicInt.value
16-
get() = get()
17-
set(value) = set(value)
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,3 @@
11
package kotlinx.coroutines
22

33
internal actual abstract class SchedulerTask : Runnable
4-
5-
internal actual interface SchedulerTaskContext { }
6-
7-
private object TaskContext: SchedulerTaskContext { }
8-
9-
internal actual val SchedulerTask.taskContext: SchedulerTaskContext get() = TaskContext
10-
11-
@Suppress("NOTHING_TO_INLINE")
12-
internal actual inline fun SchedulerTaskContext.afterTask() {}
13-

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

+5-6
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,12 @@ private class DispatcherExecutor(@JvmField val dispatcher: CoroutineDispatcher)
117117

118118
internal class ExecutorCoroutineDispatcherImpl(override val executor: Executor) : ExecutorCoroutineDispatcher(), Delay {
119119

120-
/*
121-
* Attempts to reflectively (to be Java 6 compatible) invoke
122-
* ScheduledThreadPoolExecutor.setRemoveOnCancelPolicy in order to cleanup
123-
* internal scheduler queue on cancellation.
124-
*/
125120
init {
126-
removeFutureOnCancel(executor)
121+
/* Attempt to invoke ScheduledThreadPoolExecutor.setRemoveOnCancelPolicy in order to clean up
122+
* the internal scheduler queue on cancellation. */
123+
if (executor is ScheduledThreadPoolExecutor) {
124+
executor.removeOnCancelPolicy = true
125+
}
127126
}
128127

129128
override fun dispatch(context: CoroutineContext, block: Runnable) {

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

-9
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,3 @@ package kotlinx.coroutines
33
import kotlinx.coroutines.scheduling.*
44

55
internal actual typealias SchedulerTask = Task
6-
7-
internal actual typealias SchedulerTaskContext = TaskContext
8-
9-
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
10-
internal actual val SchedulerTask.taskContext: SchedulerTaskContext get() = taskContext
11-
12-
@Suppress("NOTHING_TO_INLINE", "EXTENSION_SHADOWED_BY_MEMBER")
13-
internal actual inline fun SchedulerTaskContext.afterTask() =
14-
afterTask()

kotlinx-coroutines-core/jvm/src/flow/internal/FlowExceptions.kt

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package kotlinx.coroutines.flow.internal
22

33
import kotlinx.coroutines.*
4-
import kotlinx.coroutines.flow.*
54

65
internal actual class AbortFlowException actual constructor(
76
@JvmField @Transient actual val owner: Any
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package kotlinx.coroutines.internal
22

3-
import java.lang.reflect.*
43
import java.util.*
5-
import java.util.concurrent.*
64
import kotlin.concurrent.withLock as withLockJvm
75

86
@Suppress("ACTUAL_WITHOUT_EXPECT")
@@ -22,20 +20,3 @@ internal actual annotation class BenignDataRace()
2220
@Suppress("NOTHING_TO_INLINE") // So that R8 can completely remove ConcurrentKt class
2321
internal actual inline fun <E> identitySet(expectedSize: Int): MutableSet<E> =
2422
Collections.newSetFromMap(IdentityHashMap(expectedSize))
25-
26-
private val REMOVE_FUTURE_ON_CANCEL: Method? = try {
27-
ScheduledThreadPoolExecutor::class.java.getMethod("setRemoveOnCancelPolicy", Boolean::class.java)
28-
} catch (e: Throwable) {
29-
null
30-
}
31-
32-
@Suppress("NAME_SHADOWING")
33-
internal fun removeFutureOnCancel(executor: Executor): Boolean {
34-
try {
35-
val executor = executor as? ScheduledThreadPoolExecutor ?: return false
36-
(REMOVE_FUTURE_ON_CANCEL ?: return false).invoke(executor, true)
37-
return true
38-
} catch (e: Throwable) {
39-
return false // failed to setRemoveOnCancelPolicy, assume it does not removes future on cancel
40-
}
41-
}

kotlinx-coroutines-core/jvm/src/internal/FastServiceLoader.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package kotlinx.coroutines.internal
22

3+
import kotlinx.coroutines.CoroutineExceptionHandler
34
import java.io.*
45
import java.net.*
56
import java.util.*
67
import java.util.jar.*
78
import java.util.zip.*
8-
import kotlin.collections.ArrayList
99

1010
/**
1111
* Don't use JvmField here to enable R8 optimizations via "assumenosideeffects"
@@ -68,7 +68,7 @@ internal object FastServiceLoader {
6868
// Also search for test-module factory
6969
createInstanceOf(clz, "kotlinx.coroutines.test.internal.TestMainDispatcherFactory")?.apply { result.add(this) }
7070
result
71-
} catch (e: Throwable) {
71+
} catch (_: Throwable) {
7272
// Fallback to the regular SL in case of any unexpected exception
7373
load(clz, clz.classLoader)
7474
}
@@ -85,15 +85,15 @@ internal object FastServiceLoader {
8585
return try {
8686
val clz = Class.forName(serviceClass, true, baseClass.classLoader)
8787
baseClass.cast(clz.getDeclaredConstructor().newInstance())
88-
} catch (e: ClassNotFoundException) { // Do not fail if TestMainDispatcherFactory is not found
88+
} catch (_: ClassNotFoundException) { // Do not fail if TestMainDispatcherFactory is not found
8989
null
9090
}
9191
}
9292

9393
private fun <S> load(service: Class<S>, loader: ClassLoader): List<S> {
9494
return try {
9595
loadProviders(service, loader)
96-
} catch (e: Throwable) {
96+
} catch (_: Throwable) {
9797
// Fallback to default service loader
9898
ServiceLoader.load(service, loader).toList()
9999
}

kotlinx-coroutines-core/jvm/src/scheduling/CoroutineScheduler.kt

+24-36
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ import kotlin.math.*
7373
*
7474
* ### Support for blocking tasks
7575
*
76-
* The scheduler also supports the notion of [blocking][TASK_PROBABLY_BLOCKING] tasks.
76+
* The scheduler also supports the notion of [blocking][Task.isBlocking] tasks.
7777
* When executing or enqueuing blocking tasks, the scheduler notifies or creates an additional worker in
7878
* addition to the core pool size, so at any given moment, it has [corePoolSize] threads (potentially not yet created)
7979
* available to serve CPU-bound tasks. To properly guarantee liveness, the scheduler maintains
@@ -425,7 +425,7 @@ internal class CoroutineScheduler(
425425
block.taskContext = taskContext
426426
return block
427427
}
428-
return TaskImpl(block, nanoTime, taskContext)
428+
return block.asTask(nanoTime, taskContext)
429429
}
430430

431431
// NB: should only be called from 'dispatch' method due to blocking tasks increment
@@ -514,7 +514,7 @@ internal class CoroutineScheduler(
514514
*/
515515
if (state === WorkerState.TERMINATED) return task
516516
// Do not add CPU tasks in local queue if we are not able to execute it
517-
if (task.mode == TASK_NON_BLOCKING && state === WorkerState.BLOCKING) {
517+
if (!task.isBlocking && state === WorkerState.BLOCKING) {
518518
return task
519519
}
520520
mayHaveLocalTasks = true
@@ -810,29 +810,26 @@ internal class CoroutineScheduler(
810810
private fun inStack(): Boolean = nextParkedWorker !== NOT_IN_STACK
811811

812812
private fun executeTask(task: Task) {
813-
val taskMode = task.mode
814-
idleReset(taskMode)
815-
beforeTask(taskMode)
816-
runSafely(task)
817-
afterTask(taskMode)
818-
}
819-
820-
private fun beforeTask(taskMode: Int) {
821-
if (taskMode == TASK_NON_BLOCKING) return
822-
// Always notify about new work when releasing CPU-permit to execute some blocking task
823-
if (tryReleaseCpu(WorkerState.BLOCKING)) {
824-
signalCpuWork()
813+
terminationDeadline = 0L // reset deadline for termination
814+
if (state == WorkerState.PARKING) {
815+
assert { task.isBlocking }
816+
state = WorkerState.BLOCKING
825817
}
826-
}
827-
828-
private fun afterTask(taskMode: Int) {
829-
if (taskMode == TASK_NON_BLOCKING) return
830-
decrementBlockingTasks()
831-
val currentState = state
832-
// Shutdown sequence of blocking dispatcher
833-
if (currentState !== WorkerState.TERMINATED) {
834-
assert { currentState == WorkerState.BLOCKING } // "Expected BLOCKING state, but has $currentState"
835-
state = WorkerState.DORMANT
818+
if (task.isBlocking) {
819+
// Always notify about new work when releasing CPU-permit to execute some blocking task
820+
if (tryReleaseCpu(WorkerState.BLOCKING)) {
821+
signalCpuWork()
822+
}
823+
runSafely(task)
824+
decrementBlockingTasks()
825+
val currentState = state
826+
// Shutdown sequence of blocking dispatcher
827+
if (currentState !== WorkerState.TERMINATED) {
828+
assert { currentState == WorkerState.BLOCKING } // "Expected BLOCKING state, but has $currentState"
829+
state = WorkerState.DORMANT
830+
}
831+
} else {
832+
runSafely(task)
836833
}
837834
}
838835

@@ -923,15 +920,6 @@ internal class CoroutineScheduler(
923920
state = WorkerState.TERMINATED
924921
}
925922

926-
// It is invoked by this worker when it finds a task
927-
private fun idleReset(mode: Int) {
928-
terminationDeadline = 0L // reset deadline for termination
929-
if (state == WorkerState.PARKING) {
930-
assert { mode == TASK_PROBABLY_BLOCKING }
931-
state = WorkerState.BLOCKING
932-
}
933-
}
934-
935923
fun findTask(mayHaveLocalTasks: Boolean): Task? {
936924
if (tryAcquireCpuPermit()) return findAnyTask(mayHaveLocalTasks)
937925
/*
@@ -1013,12 +1001,12 @@ internal class CoroutineScheduler(
10131001

10141002
enum class WorkerState {
10151003
/**
1016-
* Has CPU token and either executes [TASK_NON_BLOCKING] task or tries to find one.
1004+
* Has CPU token and either executes a [Task.isBlocking]` == false` task or tries to find one.
10171005
*/
10181006
CPU_ACQUIRED,
10191007

10201008
/**
1021-
* Executing task with [TASK_PROBABLY_BLOCKING].
1009+
* Executing task with [Task.isBlocking].
10221010
*/
10231011
BLOCKING,
10241012

0 commit comments

Comments
 (0)