Description
What do we have now?
runBlocking
parks the thread holding the CPU-token if it happens on a thread of Dispatchers.Default
.
What should be instead?
runBlocking
should let go of the CPU-token before parking, and "re-acquire" the token before un-parking (it should be un-parked in state where the token is already held by it).
Why?
The current solution is just "don't use runBlocking
" followed by "at least don't use runBlocking
inside Dispatchers.Default
", which is not a solution. This does not work in real-life scenarios, especially with large mixed codebases like IJ. In IJ we've tried to leverage #3439 but the approach is stillborn because it causes #3982 but on multi-threaded scale, and we even didn't start to tackle the thread locals which leak from outer thread into inner tasks.
In other similar scenarios (FJ's managed block), another thread is spawned to compensate for the blocked one. On JVM this is the most viable approach to this day. It's better to spawn an extra thread, which might do some other work later on or just die after timeout, and to risk OOME, than to have a starvation deadlock.