diff --git a/kotlinx-coroutines-test/common/src/internal/TestMainDispatcher.kt b/kotlinx-coroutines-test/common/src/internal/TestMainDispatcher.kt index b94e261f7b..cfa77511db 100644 --- a/kotlinx-coroutines-test/common/src/internal/TestMainDispatcher.kt +++ b/kotlinx-coroutines-test/common/src/internal/TestMainDispatcher.kt @@ -9,12 +9,14 @@ import kotlin.coroutines.* * The testable main dispatcher used by kotlinx-coroutines-test. * It is a [MainCoroutineDispatcher] that delegates all actions to a settable delegate. */ -internal class TestMainDispatcher(delegate: CoroutineDispatcher): +internal class TestMainDispatcher(createInnerMain: () -> CoroutineDispatcher): MainCoroutineDispatcher(), Delay { - private val mainDispatcher = delegate - private var delegate = NonConcurrentlyModifiable(mainDispatcher, "Dispatchers.Main") + internal constructor(delegate: CoroutineDispatcher): this({ delegate }) + + private val mainDispatcher by lazy(createInnerMain) + private var delegate = NonConcurrentlyModifiable(null, "Dispatchers.Main") private val delay get() = delegate.value as? Delay ?: defaultDelay @@ -22,18 +24,21 @@ internal class TestMainDispatcher(delegate: CoroutineDispatcher): override val immediate: MainCoroutineDispatcher get() = (delegate.value as? MainCoroutineDispatcher)?.immediate ?: this - override fun dispatch(context: CoroutineContext, block: Runnable) = delegate.value.dispatch(context, block) + override fun dispatch(context: CoroutineContext, block: Runnable) = + (delegate.value ?: mainDispatcher).dispatch(context, block) - override fun isDispatchNeeded(context: CoroutineContext): Boolean = delegate.value.isDispatchNeeded(context) + override fun isDispatchNeeded(context: CoroutineContext): Boolean = + (delegate.value ?: mainDispatcher).isDispatchNeeded(context) - override fun dispatchYield(context: CoroutineContext, block: Runnable) = delegate.value.dispatchYield(context, block) + override fun dispatchYield(context: CoroutineContext, block: Runnable) = + (delegate.value ?: mainDispatcher).dispatchYield(context, block) fun setDispatcher(dispatcher: CoroutineDispatcher) { delegate.value = dispatcher } fun resetDispatcher() { - delegate.value = mainDispatcher + delegate.value = null } override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation) = diff --git a/kotlinx-coroutines-test/jvm/src/internal/TestMainDispatcherJvm.kt b/kotlinx-coroutines-test/jvm/src/internal/TestMainDispatcherJvm.kt index 1b2d7533de..3133e5c607 100644 --- a/kotlinx-coroutines-test/jvm/src/internal/TestMainDispatcherJvm.kt +++ b/kotlinx-coroutines-test/jvm/src/internal/TestMainDispatcherJvm.kt @@ -8,8 +8,7 @@ internal class TestMainDispatcherFactory : MainDispatcherFactory { override fun createDispatcher(allFactories: List): MainCoroutineDispatcher { val otherFactories = allFactories.filter { it !== this } val secondBestFactory = otherFactories.maxByOrNull { it.loadPriority } ?: MissingMainCoroutineDispatcherFactory - val dispatcher = secondBestFactory.tryCreateDispatcher(otherFactories) - return TestMainDispatcher(dispatcher) + return TestMainDispatcher({ secondBestFactory.tryCreateDispatcher(otherFactories) }) } /** @@ -24,4 +23,4 @@ internal actual fun Dispatchers.getTestMainDispatcher(): TestMainDispatcher { val mainDispatcher = Main require(mainDispatcher is TestMainDispatcher) { "TestMainDispatcher is not set as main dispatcher, have $mainDispatcher instead." } return mainDispatcher -} \ No newline at end of file +}