Skip to content

Instantly share code, notes, and snippets.

@octylFractal
Created March 25, 2020 08:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save octylFractal/4fb0ff0fe7fb25cb26d173ba1b3fcbf1 to your computer and use it in GitHub Desktop.
Save octylFractal/4fb0ff0fe7fb25cb26d173ba1b3fcbf1 to your computer and use it in GitHub Desktop.
import kotlinx.coroutines.*
import java.util.concurrent.LinkedBlockingQueue
import kotlin.coroutines.CoroutineContext
fun main() {
val queue = LinkedBlockingQueue<Runnable>()
val mainDispatcher = ArbitraryMainDispatcher(Thread.currentThread(), queue = { queue.add(it) })
CoroutineScope(mainDispatcher).launch {
println("${Thread.currentThread()} On the main dispatcher!")
withContext(Dispatchers.IO) {
println("${Thread.currentThread()} On the IO dispatcher!")
}
println("${Thread.currentThread()} Back on the main dispatcher!")
}
while (true) {
queue.take().run()
}
}
sealed class ArbitraryMainDispatcherBase(
private val queue: (Runnable) -> Unit
) : MainCoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
queue(block)
}
}
/**
* Arbitrary main dispatcher -- considers [thread] to be the main thread.
*
* Queues runnables using [queue] -- this should eventually call the runnable
* on the [thread].
*/
class ArbitraryMainDispatcher(
private val thread: Thread,
private val queue: (Runnable) -> Unit
) : ArbitraryMainDispatcherBase(queue) {
override val immediate: MainCoroutineDispatcher
get() = ImmediateArbitraryMainDispatcher(thread, queue)
}
private class ImmediateArbitraryMainDispatcher(
private val thread: Thread,
queue: (Runnable) -> Unit
) : ArbitraryMainDispatcherBase(queue) {
override val immediate: MainCoroutineDispatcher
get() = this
override fun isDispatchNeeded(context: CoroutineContext) = Thread.currentThread() != thread
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment