From 83e8c471913b0bf9b36bef3db3d90483db2c26b7 Mon Sep 17 00:00:00 2001 From: Vsevolod Tolstopyatov Date: Tue, 18 Aug 2020 19:08:04 +0300 Subject: [PATCH] Cherry-picks from native-mt branch to reduce maintenance burden * Immediate dispatcher on JS, test added * Style fixes --- buildSrc/src/main/kotlin/Idea.kt | 1 + kotlinx-coroutines-core/js/src/Dispatchers.kt | 21 +++++------- .../js/test/ImmediateDispatcherTest.kt | 32 +++++++++++++++++++ kotlinx-coroutines-core/jvm/src/Executors.kt | 2 +- .../native/src/Dispatchers.kt | 8 ----- .../build.gradle.kts | 4 --- 6 files changed, 42 insertions(+), 26 deletions(-) create mode 100644 kotlinx-coroutines-core/js/test/ImmediateDispatcherTest.kt diff --git a/buildSrc/src/main/kotlin/Idea.kt b/buildSrc/src/main/kotlin/Idea.kt index 802b387b0d..615b8aad74 100644 --- a/buildSrc/src/main/kotlin/Idea.kt +++ b/buildSrc/src/main/kotlin/Idea.kt @@ -1,4 +1,5 @@ object Idea { + @JvmStatic // for Gradle val active: Boolean get() = System.getProperty("idea.active") == "true" } diff --git a/kotlinx-coroutines-core/js/src/Dispatchers.kt b/kotlinx-coroutines-core/js/src/Dispatchers.kt index 033b39c7e0..06b938d41a 100644 --- a/kotlinx-coroutines-core/js/src/Dispatchers.kt +++ b/kotlinx-coroutines-core/js/src/Dispatchers.kt @@ -7,24 +7,19 @@ package kotlinx.coroutines import kotlin.coroutines.* public actual object Dispatchers { - public actual val Default: CoroutineDispatcher = createDefaultDispatcher() - - public actual val Main: MainCoroutineDispatcher = JsMainDispatcher(Default) - + public actual val Main: MainCoroutineDispatcher = JsMainDispatcher(Default, false) public actual val Unconfined: CoroutineDispatcher = kotlinx.coroutines.Unconfined } -private class JsMainDispatcher(val delegate: CoroutineDispatcher) : MainCoroutineDispatcher() { - - override val immediate: MainCoroutineDispatcher - get() = throw UnsupportedOperationException("Immediate dispatching is not supported on JS") - +private class JsMainDispatcher( + val delegate: CoroutineDispatcher, + private val invokeImmediately: Boolean +) : MainCoroutineDispatcher() { + override val immediate: MainCoroutineDispatcher = + if (invokeImmediately) this else JsMainDispatcher(delegate, true) + override fun isDispatchNeeded(context: CoroutineContext): Boolean = !invokeImmediately override fun dispatch(context: CoroutineContext, block: Runnable) = delegate.dispatch(context, block) - - override fun isDispatchNeeded(context: CoroutineContext): Boolean = delegate.isDispatchNeeded(context) - override fun dispatchYield(context: CoroutineContext, block: Runnable) = delegate.dispatchYield(context, block) - override fun toString(): String = toStringInternalImpl() ?: delegate.toString() } diff --git a/kotlinx-coroutines-core/js/test/ImmediateDispatcherTest.kt b/kotlinx-coroutines-core/js/test/ImmediateDispatcherTest.kt new file mode 100644 index 0000000000..7ca6a242b2 --- /dev/null +++ b/kotlinx-coroutines-core/js/test/ImmediateDispatcherTest.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +package kotlinx.coroutines + +import kotlin.test.* + +class ImmediateDispatcherTest : TestBase() { + + @Test + fun testImmediate() = runTest { + expect(1) + val job = launch { expect(3) } + withContext(Dispatchers.Main.immediate) { + expect(2) + } + job.join() + finish(4) + } + + @Test + fun testMain() = runTest { + expect(1) + val job = launch { expect(2) } + withContext(Dispatchers.Main) { + expect(3) + } + job.join() + finish(4) + } +} diff --git a/kotlinx-coroutines-core/jvm/src/Executors.kt b/kotlinx-coroutines-core/jvm/src/Executors.kt index a4d6b46c43..8c36bfa14f 100644 --- a/kotlinx-coroutines-core/jvm/src/Executors.kt +++ b/kotlinx-coroutines-core/jvm/src/Executors.kt @@ -14,7 +14,7 @@ import kotlin.coroutines.* * Instances of [ExecutorCoroutineDispatcher] should be closed by the owner of the dispatcher. * * This class is generally used as a bridge between coroutine-based API and - * asynchronous API which requires instance of the [Executor]. + * asynchronous API that requires an instance of the [Executor]. */ public abstract class ExecutorCoroutineDispatcher: CoroutineDispatcher(), Closeable { /** @suppress */ diff --git a/kotlinx-coroutines-core/native/src/Dispatchers.kt b/kotlinx-coroutines-core/native/src/Dispatchers.kt index aca1cc0693..c06b7c2f0a 100644 --- a/kotlinx-coroutines-core/native/src/Dispatchers.kt +++ b/kotlinx-coroutines-core/native/src/Dispatchers.kt @@ -7,24 +7,16 @@ package kotlinx.coroutines import kotlin.coroutines.* public actual object Dispatchers { - public actual val Default: CoroutineDispatcher = createDefaultDispatcher() - public actual val Main: MainCoroutineDispatcher = NativeMainDispatcher(Default) - public actual val Unconfined: CoroutineDispatcher get() = kotlinx.coroutines.Unconfined // Avoid freezing } private class NativeMainDispatcher(val delegate: CoroutineDispatcher) : MainCoroutineDispatcher() { - override val immediate: MainCoroutineDispatcher get() = throw UnsupportedOperationException("Immediate dispatching is not supported on Native") - override fun dispatch(context: CoroutineContext, block: Runnable) = delegate.dispatch(context, block) - override fun isDispatchNeeded(context: CoroutineContext): Boolean = delegate.isDispatchNeeded(context) - override fun dispatchYield(context: CoroutineContext, block: Runnable) = delegate.dispatchYield(context, block) - override fun toString(): String = toStringInternalImpl() ?: delegate.toString() } diff --git a/ui/kotlinx-coroutines-android/build.gradle.kts b/ui/kotlinx-coroutines-android/build.gradle.kts index 4be32fc5c6..7c9e7020b5 100644 --- a/ui/kotlinx-coroutines-android/build.gradle.kts +++ b/ui/kotlinx-coroutines-android/build.gradle.kts @@ -6,10 +6,6 @@ import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink import org.jetbrains.dokka.gradle.DokkaTask import java.net.URL -repositories { - google() -} - configurations { create("r8") }