mirror of
https://github.com/tursom/TursomServer.git
synced 2025-03-14 03:40:06 +08:00
add MainCoroutineDispatcherFactory
This commit is contained in:
parent
a1046bca98
commit
b26f89ff5e
@ -1,6 +1,7 @@
|
||||
package cn.tursom.utils.coroutine
|
||||
|
||||
import cn.tursom.core.cast
|
||||
import cn.tursom.core.toHexString
|
||||
import kotlinx.coroutines.Job
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
@ -43,6 +44,8 @@ open class CoroutineLocal<T> {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun toString(): String = "CoroutineLocal@${hashCode().toHexString(false)}"
|
||||
|
||||
companion object {
|
||||
private val attachMap = ConcurrentHashMap<CoroutineContext, MutableMap<CoroutineLocal<*>, Any?>>()
|
||||
override fun toString(): String = attachMap.toString()
|
||||
|
@ -0,0 +1,13 @@
|
||||
package cn.tursom.utils.coroutine
|
||||
|
||||
import kotlinx.coroutines.InternalCoroutinesApi
|
||||
import kotlinx.coroutines.MainCoroutineDispatcher
|
||||
import kotlinx.coroutines.internal.MainDispatcherFactory
|
||||
|
||||
@Suppress("unused")
|
||||
@InternalCoroutinesApi
|
||||
class MainCoroutineDispatcherFactory : MainDispatcherFactory {
|
||||
override val loadPriority: Int = 1
|
||||
|
||||
override fun createDispatcher(allFactories: List<MainDispatcherFactory>): MainCoroutineDispatcher = MainDispatcher
|
||||
}
|
@ -1,27 +1,42 @@
|
||||
package cn.tursom.utils.coroutine
|
||||
|
||||
import cn.tursom.core.cast
|
||||
import kotlinx.coroutines.ExecutorCoroutineDispatcher
|
||||
import kotlinx.coroutines.MainCoroutineDispatcher
|
||||
import kotlinx.coroutines.asCoroutineDispatcher
|
||||
import java.io.Closeable
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Modifier
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import kotlin.concurrent.thread
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
object MainDispatcher : MainCoroutineDispatcher(), Closeable {
|
||||
private val dispatcher = Executors.newSingleThreadExecutor {
|
||||
thread(start = false, block = it::run, name = "mainDispatcher", isDaemon = false)
|
||||
private val loaded = AtomicBoolean(false)
|
||||
private val dispatcher: ExecutorCoroutineDispatcher = Executors.newSingleThreadExecutor {
|
||||
thread(start = false, block = it::run, name = "MainDispatcher", isDaemon = false)
|
||||
}.asCoroutineDispatcher()
|
||||
|
||||
fun init() {
|
||||
val mainDispatcherLoader = Class.forName("kotlinx.coroutines.internal.MainDispatcherLoader")
|
||||
val dispatcher = mainDispatcherLoader.getDeclaredField("dispatcher")
|
||||
private var oldDispatcher: MainCoroutineDispatcher? = null
|
||||
private val mainDispatcherLoader: Class<*> = Class.forName("kotlinx.coroutines.internal.MainDispatcherLoader")
|
||||
private val dispatcherField: Field = mainDispatcherLoader.getDeclaredField("dispatcher").also { dispatcher ->
|
||||
dispatcher.isAccessible = true
|
||||
val mf: Field = Field::class.java.getDeclaredField("modifiers")
|
||||
mf.isAccessible = true
|
||||
mf.setInt(dispatcher, dispatcher.modifiers and Modifier.FINAL.inv())
|
||||
dispatcher.set(null, this)
|
||||
}
|
||||
|
||||
fun init() {
|
||||
if (loaded.compareAndSet(false, true)) {
|
||||
oldDispatcher = dispatcherField.get(null).cast()
|
||||
dispatcherField.set(null, this)
|
||||
}
|
||||
}
|
||||
|
||||
fun resume() {
|
||||
if (loaded.compareAndSet(true, false) && oldDispatcher != null) {
|
||||
dispatcherField.set(null, oldDispatcher)
|
||||
}
|
||||
}
|
||||
|
||||
override val immediate: MainCoroutineDispatcher get() = this
|
||||
|
@ -218,4 +218,12 @@ fun combinedContext(coroutineContext: CoroutineContext): Boolean {
|
||||
left.set(coroutineContext, leftObj + CoroutineLocalContext())
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
//fun CoroutineScope.runOnUiThread(action: suspend CoroutineScope.() -> Unit): Job {
|
||||
// return launch(Dispatchers.Main, block = action)
|
||||
//}
|
||||
|
||||
suspend fun <T> runOnUiThread(action: suspend CoroutineScope.() -> T): T {
|
||||
return withContext(Dispatchers.Main, action)
|
||||
}
|
@ -0,0 +1 @@
|
||||
cn.tursom.utils.coroutine.MainDispatcherFactory
|
@ -23,23 +23,29 @@ interface CoroutineLocalTest {
|
||||
}
|
||||
|
||||
class Test : CoroutineScope by MainScope() {
|
||||
suspend fun test(): Job {
|
||||
println(this)
|
||||
suspend fun test() {
|
||||
testCoroutineLocal.set(1)
|
||||
println(coroutineContext)
|
||||
return coroutineScope {
|
||||
println(this)
|
||||
coroutineScope {
|
||||
println(coroutineContext)
|
||||
println(Thread.currentThread().name)
|
||||
delay(1)
|
||||
return@coroutineScope launch {
|
||||
println(Thread.currentThread().name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun main() {
|
||||
MainDispatcher.init()
|
||||
Test().test().join()
|
||||
//MainDispatcher.init()
|
||||
runOnUiThread {
|
||||
Test().test()
|
||||
println(testCoroutineLocal.get())
|
||||
println(coroutineContext)
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
println(coroutineContext)
|
||||
}
|
||||
//runOnUiThread {
|
||||
// println(coroutineContext)
|
||||
// println(testCoroutineLocal.get())
|
||||
//}
|
||||
}
|
||||
MainDispatcher.close()
|
||||
}
|
Loading…
Reference in New Issue
Block a user