https://kotlinlang.org logo
#coroutines
Title
# coroutines
d

Daniel Pitts

12/13/2023, 9:15 PM
Other than starting a new single threaded executor dispatcher, is there a way to pin a suspend block to a single thread? This is on the JVM.
Specifically, I have some external code which uses thread local data between calls, so I need to ensure that the thread stays the same during the operation. Oh the joys of OpenGL.
To be more specific, this is JVM but its not using the
ThreadLocal
, but in a JNI library there is thread-local context.
s

Sam

12/14/2023, 8:51 AM
Starting a
newSingleThreadContext()
is the right way if you want to create a new dedicated thread for your coroutine to run on. There could be other ways to do it if you want to run the coroutines on some existing thread that already exists in your application, though. For example: •
runBlocking
takes control of its calling thread, and creates an event loop dispatcher to run coroutines on that thread. • Android's
Handler.asCoroutineDispatcher()
will dispatch coroutines to the looper of an existing
Handler
. •
Executor.asCoroutineDispatcher()
will dispatch coroutines to any existing executor in your application.
Other than controlling the dispatcher, you can't specify which thread you want a coroutine to run on, or mandate any particular threading policy.
You can have a coroutine carry its thread local context around with it, though! Take a look at
ThreadContextElement
and
CopyableThreadContextElement
. These will be invoked every time the coroutine is dispatched to a thread. If you can access and control the thread context you want to set, you could write a
ThreadContextElement
to move it from thread to thread as the coroutine is dispatched. The slf4j coroutines integration uses this approach to copy the MDC.
thank you color 1
d

Daniel Pitts

12/14/2023, 3:02 PM
I’ll have to think about this more. The resource management around this particular context means it would have to be removed from the old thread before being moved to the new thread. I might need to create a “use” style method that manages this and sets up the dispatcher.