Exerosis
05/22/2023, 10:42 AMclass Reentrant : Key<Reentrant>, Element {
val lock = Mutex()
override val key get() = this
suspend fun <Return> withLock(block: suspend () -> (Return)): Return {
if (currentCoroutineContext()[this] != null) return block()
return lock.withLock { withContext(this) { block() } }
}
}
Or something along these lines... we do want to make sure that:
reentrant.withLock {
GlobalScope.launch {
reentrannt.withLock {}
}
}
Is not considered recursive. I was thinking perhaps I could abuse CopyableThreadContextElement and make copyForChild return some kind of EmptyCopyableThreadContextElement. But maybe there is a better way? Seems like this might not even work because it always calls copy if the element is on the right side of newCoroutineContextephemient
05/22/2023, 10:37 PMGlobalScope.launch
Exerosis
05/23/2023, 7:49 PMExerosis
05/23/2023, 7:55 PMfun main() {
runBlocking {
println("Name: ${currentCoroutineContext()[CoroutineName]}")
withContext(CoroutineName("test")) {
println("Name: ${currentCoroutineContext()[CoroutineName]}")
launch {
println("Name: ${currentCoroutineContext()[CoroutineName]}")
}
}
}
}
Result:
Name: null
Name: CoroutineName(test)
Name: CoroutineName(test)
I need a context that doesn't make it into launch/async or any block that isn't executed sequentially.ephemient
05/23/2023, 7:59 PMlaunch
, but not with GlobalScope.launch
as in your original exampleExerosis
05/23/2023, 10:11 PMephemient
05/23/2023, 10:12 PMephemient
05/23/2023, 10:13 PMephemient
05/23/2023, 10:13 PMExerosis
05/24/2023, 7:56 PMreentrant.withLock {
launch {
reentrannt.withLock {}
}
}
Exerosis
05/24/2023, 7:56 PMephemient
05/24/2023, 8:08 PMExerosis
05/25/2023, 8:10 PMExerosis
05/25/2023, 8:14 PM