-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathDispatchers.kt
64 lines (52 loc) · 2.81 KB
/
Dispatchers.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package kotlinx.coroutines
import kotlinx.coroutines.internal.multithreadingSupported
import kotlin.coroutines.*
import kotlin.native.concurrent.*
public actual object Dispatchers {
public actual val Default: CoroutineDispatcher = createDefaultDispatcherBasedOnMm()
public actual val Main: MainCoroutineDispatcher
get() = injectedMainDispatcher ?: mainDispatcher
public actual val Unconfined: CoroutineDispatcher get() = kotlinx.coroutines.Unconfined // Avoid freezing
private val mainDispatcher = createMainDispatcher(Default)
private var injectedMainDispatcher: MainCoroutineDispatcher? = null
@PublishedApi
internal fun injectMain(dispatcher: MainCoroutineDispatcher) {
if (!multithreadingSupported) {
throw IllegalStateException("Dispatchers.setMain is not supported in Kotlin/Native when new memory model is disabled")
}
injectedMainDispatcher = dispatcher
}
}
/**
* Does this platform define a Main dispatcher?
*/
@PublishedApi
@SharedImmutable
internal expect val mainDispatcherIsPresent: Boolean
internal expect fun createMainDispatcher(default: CoroutineDispatcher): MainCoroutineDispatcher
private fun createDefaultDispatcherBasedOnMm(): CoroutineDispatcher {
return if (multithreadingSupported) createDefaultDispatcher()
else OldDefaultExecutor
}
private fun takeEventLoop(): EventLoopImpl =
ThreadLocalEventLoop.currentOrNull() as? EventLoopImpl ?:
error("There is no event loop. Use runBlocking { ... } to start one.")
internal object OldDefaultExecutor : CoroutineDispatcher(), Delay {
override fun dispatch(context: CoroutineContext, block: Runnable) =
takeEventLoop().dispatch(context, block)
override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation<Unit>) =
takeEventLoop().scheduleResumeAfterDelay(timeMillis, continuation)
override fun invokeOnTimeout(timeMillis: Long, block: Runnable, context: CoroutineContext): DisposableHandle =
takeEventLoop().invokeOnTimeout(timeMillis, block, context)
}
internal class OldMainDispatcher(private 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()
}