|
5 | 5 | package kotlinx.coroutines.internal
|
6 | 6 |
|
7 | 7 | import kotlinx.coroutines.*
|
| 8 | +import java.util.* |
8 | 9 | import kotlin.coroutines.*
|
9 | 10 |
|
| 11 | +/** |
| 12 | + * Name of the boolean property that enables using of [FastServiceLoader]. |
| 13 | + */ |
| 14 | +private const val FAST_SERVICE_LOADER_PROPERTY_NAME = "kotlinx.coroutines.fast.service.loader" |
| 15 | + |
| 16 | +// Lazy loader for the main dispatcher |
| 17 | +internal object MainDispatcherLoader { |
| 18 | + |
| 19 | + private val FAST_SERVICE_LOADER_ENABLED = systemProp(FAST_SERVICE_LOADER_PROPERTY_NAME, true) |
| 20 | + |
| 21 | + @JvmField |
| 22 | + val dispatcher: MainCoroutineDispatcher = loadMainDispatcher() |
| 23 | + |
| 24 | + private fun loadMainDispatcher(): MainCoroutineDispatcher { |
| 25 | + return try { |
| 26 | + val factories = if (FAST_SERVICE_LOADER_ENABLED) { |
| 27 | + FastServiceLoader.loadMainDispatcherFactory() |
| 28 | + } else { |
| 29 | + // We are explicitly using the |
| 30 | + // `ServiceLoader.load(MyClass::class.java, MyClass::class.java.classLoader).iterator()` |
| 31 | + // form of the ServiceLoader call to enable R8 optimization when compiled on Android. |
| 32 | + ServiceLoader.load( |
| 33 | + MainDispatcherFactory::class.java, |
| 34 | + MainDispatcherFactory::class.java.classLoader |
| 35 | + ).iterator().asSequence().toList() |
| 36 | + } |
| 37 | + @Suppress("ConstantConditionIf") |
| 38 | + factories.maxByOrNull { it.loadPriority }?.tryCreateDispatcher(factories) |
| 39 | + ?: createMissingDispatcher() |
| 40 | + } catch (e: Throwable) { |
| 41 | + // Service loader can throw an exception as well |
| 42 | + createMissingDispatcher(e) |
| 43 | + } |
| 44 | + } |
| 45 | +} |
| 46 | + |
10 | 47 | /**
|
11 | 48 | * If anything goes wrong while trying to create main dispatcher (class not found,
|
12 | 49 | * initialization failed, etc), then replace the main dispatcher with a special
|
@@ -34,7 +71,7 @@ private val SUPPORT_MISSING = true
|
34 | 71 | "ConstantConditionIf",
|
35 | 72 | "IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE" // KT-47626
|
36 | 73 | )
|
37 |
| -internal fun createMissingDispatcher(cause: Throwable? = null, errorHint: String? = null): MainCoroutineDispatcher = |
| 74 | +private fun createMissingDispatcher(cause: Throwable? = null, errorHint: String? = null) = |
38 | 75 | if (SUPPORT_MISSING) MissingMainCoroutineDispatcher(cause, errorHint) else
|
39 | 76 | cause?.let { throw it } ?: throwMissingMainDispatcherException()
|
40 | 77 |
|
|
0 commit comments