add CoroutineLocalContinuation

This commit is contained in:
tursom 2020-07-18 17:36:16 +08:00
parent f4ec9ca3c8
commit 3b8baada36
3 changed files with 83 additions and 27 deletions

View File

@ -0,0 +1,11 @@
package cn.tursom.utils.coroutine
import cn.tursom.core.cast
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
class CoroutineLocalContinuation(
private val completion: Continuation<*>
) : Continuation<Any?> by completion.cast() {
override val context: CoroutineContext = completion.context + CoroutineLocalContext()
}

View File

@ -1,8 +1,11 @@
package cn.tursom.utils.coroutine package cn.tursom.utils.coroutine
import cn.tursom.core.cast
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.coroutineContext
fun CoroutineScope.launchWithCoroutineLocalContext( fun CoroutineScope.launchWithCoroutineLocalContext(
@ -117,4 +120,25 @@ fun <T> runBlockingWithEnhanceContext(
return runBlocking(context + CoroutineLocalContext(map)) { return runBlocking(context + CoroutineLocalContext(map)) {
block() block()
} }
}
suspend inline fun <T> runWithCoroutineLocalContext(block: () -> T): T {
return (block.cast<(Continuation<*>) -> T>()).invoke(CoroutineLocalContinuation(getContinuation()))
}
suspend inline fun <T> runWithCoroutineLocal(block: () -> T): T {
if (coroutineContext[CoroutineLocalContext] == null) {
return runWithCoroutineLocalContext(block)
}
return block()
}
@Suppress("NOTHING_TO_INLINE")
inline fun getContinuation(continuation: Continuation<*>): Continuation<*> {
return continuation
}
suspend inline fun getContinuation(): Continuation<*> {
val getContinuation: (continuation: Continuation<*>) -> Continuation<*> = ::getContinuation
return (getContinuation.cast<suspend () -> Continuation<*>>()).invoke()
} }

View File

@ -1,12 +1,12 @@
package cn.tursom.utils.coroutine package cn.tursom.utils.coroutine
import kotlinx.coroutines.* import cn.tursom.core.cast
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlin.coroutines.Continuation
import kotlin.coroutines.coroutineContext import kotlin.coroutines.coroutineContext
val testCoroutineLocal = CoroutineLocal<Int>() val testCoroutineLocal = CoroutineLocal<Int>()
val testCoroutineLocalList = Array(100000) {
CoroutineLocal<Int>()
}.asList()
suspend fun test() { suspend fun test() {
println(coroutineContext) println(coroutineContext)
@ -15,30 +15,51 @@ suspend fun test() {
println(Thread.currentThread().name) println(Thread.currentThread().name)
} }
suspend fun main() { @Suppress("NOTHING_TO_INLINE")
CurrentThreadCoroutineScope.launch { inline fun getContinuation(continuation: Continuation<*>): Continuation<*> {
println("Unconfined : I'm working in thread ${Thread.currentThread().name}") return continuation
delay(50) }
println("Unconfined : After delay in thread ${Thread.currentThread().name}")
delay(50) suspend inline fun getContinuation(): Continuation<*> {
println("Unconfined : After delay in thread ${Thread.currentThread().name}") val getContinuation: (continuation: Continuation<*>) -> Continuation<*> = ::getContinuation
return (getContinuation.cast<suspend () -> Continuation<*>>()).invoke()
}
suspend fun testCustomContext(): Int? = runWithCoroutineLocal {
println(coroutineContext)
return testCoroutineLocal.get()
}
suspend fun main(): Unit = runWithCoroutineLocal {
repeat(100) {
testCoroutineLocal.set(it)
println(testCustomContext())
} }
GlobalScope.launch(Dispatchers.Unconfined) { // 非受限的——将和主线程一起工作 ////println(::main.javaMethod?.parameters?.get(0))
println("Unconfined : I'm working in thread ${Thread.currentThread().name}") //println(coroutineContext)
delay(50) //CurrentThreadCoroutineScope.launch {
println("Unconfined : After delay in thread ${Thread.currentThread().name}") // println("Unconfined : I'm working in thread ${Thread.currentThread().name}")
delay(50) // delay(50)
println("Unconfined : After delay in thread ${Thread.currentThread().name}") // println("Unconfined : After delay in thread ${Thread.currentThread().name}")
} // delay(50)
GlobalScope.launch { // 父协程的上下文,主 runBlocking 协程 // println("Unconfined : After delay in thread ${Thread.currentThread().name}")
println("main runBlocking: I'm working in thread ${Thread.currentThread().name}") //}
delay(100) //GlobalScope.launch(Dispatchers.Unconfined) { // 非受限的——将和主线程一起工作
println("main runBlocking: After delay in thread ${Thread.currentThread().name}") // println("Unconfined : I'm working in thread ${Thread.currentThread().name}")
delay(100) // delay(50)
println("main runBlocking: After delay in thread ${Thread.currentThread().name}") // println("Unconfined : After delay in thread ${Thread.currentThread().name}")
} // delay(50)
println("end") // println("Unconfined : After delay in thread ${Thread.currentThread().name}")
delay(1000) //}
//GlobalScope.launch { // 父协程的上下文,主 runBlocking 协程
// println("main runBlocking: I'm working in thread ${Thread.currentThread().name}")
// delay(100)
// println("main runBlocking: After delay in thread ${Thread.currentThread().name}")
// delay(100)
// println("main runBlocking: After delay in thread ${Thread.currentThread().name}")
//}
//println("end")
//delay(1000)
//runBlockingWithEnhanceContext { //runBlockingWithEnhanceContext {
// println(coroutineContext) // println(coroutineContext)
// println(coroutineContext[Job] is CoroutineScope) // println(coroutineContext[Job] is CoroutineScope)