runBlockingIfRequired

fun <T> runBlockingIfRequired(context: CoroutineContext = EmptyCoroutineContext, block: suspend () -> T): T(source)

Executes a suspending block as a bridge from blocking (Java) code into the coroutine world. It uses AGENT_CONTEXT_ELEMENT to track the current logical dispatcher across blocking boundaries and avoid deadlocks in two scenarios:

Re-entrant call (AGENT_CONTEXT_ELEMENT is set): the current thread is already inside a runBlocking started by this function. If the target dispatcher matches the existing one, using runBlocking(context) would try to re-dispatch onto the same executor — which may be single-threaded and already blocked. runBlocking(EmptyCoroutineContext) avoids the re-dispatch by running inline on the current thread's event loop instead.

First entry (AGENT_CONTEXT_ELEMENT is null): the calling thread may itself be a worker of the target executor (e.g. agent.run() called from inside executor.submit()). In that case, runBlocking(context) would dispatch the coroutine onto the executor and then park the calling thread waiting for it — but the calling thread IS the only worker, so the coroutine never runs. runBlocking(EmptyCoroutineContext) runs the coroutine inline on the current thread, bypassing the executor queue entirely. The TARGET context is stored in AGENT_CONTEXT_ELEMENT (not the actual coroutineContext) so that nested calls can still compare dispatchers correctly.

Return

The result of the block.

Parameters

context

The coroutine context to use for execution. Defaults to EmptyCoroutineContext.

block

The suspending block to execute.