Skip to content

Commit

Permalink
Fix kotlinx.coroutines.main.delay being ignored (Kotlin#3046)
Browse files Browse the repository at this point in the history
Fix reading an uninitialized value of defaultMainDelayOptIn due to
the initialization cycle and add a test that ensures this behaviour in the future

Fixes Kotlin#3044
  • Loading branch information
qwwdfsad committed Dec 10, 2021
1 parent 867b78c commit 19cefbf
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 3 deletions.
4 changes: 2 additions & 2 deletions kotlinx-coroutines-core/jvm/src/DefaultExecutor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import kotlinx.coroutines.internal.*
import java.util.concurrent.*
import kotlin.coroutines.*

internal actual val DefaultDelay: Delay = initializeDefaultDelay()

private val defaultMainDelayOptIn = systemProp("kotlinx.coroutines.main.delay", true)

internal actual val DefaultDelay: Delay = initializeDefaultDelay()

private fun initializeDefaultDelay(): Delay {
// Opt-out flag
if (!defaultMainDelayOptIn) return DefaultExecutor
Expand Down
4 changes: 3 additions & 1 deletion kotlinx-coroutines-core/jvm/src/internal/MainDispatchers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ public fun MainDispatcherFactory.tryCreateDispatcher(factories: List<MainDispatc

/** @suppress */
@InternalCoroutinesApi
public fun MainCoroutineDispatcher.isMissing(): Boolean = this is MissingMainCoroutineDispatcher
public fun MainCoroutineDispatcher.isMissing(): Boolean =
// not checking `this`, as it may be wrapped in a `TestMainDispatcher`, whereas `immediate` never is.
this.immediate is MissingMainCoroutineDispatcher

// R8 optimization hook, not const on purpose to enable R8 optimizations via "assumenosideeffects"
@Suppress("MayBeConstant")
Expand Down
18 changes: 18 additions & 0 deletions ui/kotlinx-coroutines-android/test/HandlerDispatcherTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,22 @@ class HandlerDispatcherTest : TestBase() {
assertEquals("Dispatchers.Main", Dispatchers.Main.toString())
assertEquals("Dispatchers.Main.immediate", Dispatchers.Main.immediate.toString())
}

@Test
fun testDelayIsDelegatedToMain() = runTest {
val mainLooper = shadowOf(Looper.getMainLooper())
mainLooper.pause()
val mainMessageQueue = shadowOf(Looper.getMainLooper().queue)
assertNull(mainMessageQueue.head)
val job = launch(Dispatchers.Default, start = CoroutineStart.UNDISPATCHED) {
expect(1)
delay(10_000_000)
expect(3)
}
expect(2)
assertNotNull(mainMessageQueue.head)
mainLooper.runOneTask()
job.join()
finish(4)
}
}

0 comments on commit 19cefbf

Please sign in to comment.