Skip to content

Instantly share code, notes, and snippets.

@omkar-tenkale
Created June 3, 2023 11:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save omkar-tenkale/36141fa9291c759071bbb7b7b20d4dc7 to your computer and use it in GitHub Desktop.
Save omkar-tenkale/36141fa9291c759071bbb7b7b20d4dc7 to your computer and use it in GitHub Desktop.
import java.lang.Exception
import kotlin.concurrent.thread
import java.util.concurrent.Executors
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.intrinsics.createCoroutineUnintercepted
import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
fun main() {
launch(Dispatcher.Main) {
println("Download started - $threadName")
download()
println("Download complete - $threadName")
}
}
val threadName get() = Thread.currentThread().name
val dummyMainThread = Executors.newSingleThreadExecutor { Thread(it, "main") }
suspend fun download() {
suspendCoroutineUninterceptedOrReturn<Unit> { cont ->
thread {
println("Download in progress - $threadName")
when (cont.context as Dispatcher) {
Dispatcher.Main -> dummyMainThread.execute {
cont.resumeWith(Result.success(Unit))
}
Dispatcher.Background -> thread {
cont.resumeWith(Result.success(Unit))
}
}
}
COROUTINE_SUSPENDED
}
}
sealed class Dispatcher : CoroutineContext.Element {
object Main : Dispatcher()
object Background : Dispatcher()
override val key = DispatcherKey
}
object DispatcherKey : CoroutineContext.Key<Dispatcher> {}
fun launch(dispatcher: Dispatcher, block: suspend () -> Unit) {
val callback = object : Continuation<Unit> {
// Passing dispatcher as CoroutineContext
override val context: CoroutineContext = dispatcher
override fun resumeWith(result: Result<Unit>) {}
}
val coroutine = block.createCoroutineUnintercepted(callback)
when (dispatcher) {
Dispatcher.Main -> dummyMainThread.execute {
coroutine.resumeWith(Result.success(Unit))
}
Dispatcher.Background -> thread {
coroutine.resumeWith(Result.success(Unit))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment