diff --git a/kotlinx-coroutines-core/jvm/src/DefaultExecutor.kt b/kotlinx-coroutines-core/jvm/src/DefaultExecutor.kt index 2968825d15..e13ca7b472 100644 --- a/kotlinx-coroutines-core/jvm/src/DefaultExecutor.kt +++ b/kotlinx-coroutines-core/jvm/src/DefaultExecutor.kt @@ -4,10 +4,25 @@ package kotlinx.coroutines +import kotlinx.coroutines.internal.* import java.util.concurrent.* import kotlin.coroutines.* -internal actual val DefaultDelay: Delay = DefaultExecutor +internal actual val DefaultDelay: Delay = initializeDefaultDelay() + +private val defaultMainDelayOptIn = systemProp("kotlinx.coroutines.main.delay", true) + +private fun initializeDefaultDelay(): Delay { + // Opt-out flag + if (!defaultMainDelayOptIn) return DefaultExecutor + val main = Dispatchers.Main + /* + * When we already are working with UI and Main threads, it makes + * no sense to create a separate thread with timer that cannot be controller + * by the UI runtime. + */ + return if (main.isMissing() || main !is Delay) DefaultExecutor else main +} @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") internal actual object DefaultExecutor : EventLoopImplBase(), Runnable { diff --git a/ui/kotlinx-coroutines-javafx/src/JavaFxDispatcher.kt b/ui/kotlinx-coroutines-javafx/src/JavaFxDispatcher.kt index 0a35cbf22e..7425038826 100644 --- a/ui/kotlinx-coroutines-javafx/src/JavaFxDispatcher.kt +++ b/ui/kotlinx-coroutines-javafx/src/JavaFxDispatcher.kt @@ -35,22 +35,18 @@ public sealed class JavaFxDispatcher : MainCoroutineDispatcher(), Delay { /** @suppress */ override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation) { - val timeline = schedule(timeMillis, TimeUnit.MILLISECONDS, EventHandler { + val timeline = schedule(timeMillis, TimeUnit.MILLISECONDS) { with(continuation) { resumeUndispatched(Unit) } - }) + } continuation.invokeOnCancellation { timeline.stop() } } /** @suppress */ override fun invokeOnTimeout(timeMillis: Long, block: Runnable, context: CoroutineContext): DisposableHandle { - val timeline = schedule(timeMillis, TimeUnit.MILLISECONDS, EventHandler { + val timeline = schedule(timeMillis, TimeUnit.MILLISECONDS) { block.run() - }) - return object : DisposableHandle { - override fun dispose() { - timeline.stop() - } } + return DisposableHandle { timeline.stop() } } private fun schedule(time: Long, unit: TimeUnit, handler: EventHandler): Timeline =