@@ -155,6 +155,11 @@ public suspend fun <T> run(context: CoroutineContext, block: suspend () -> T): T
155155 * in this blocked thread until the completion of this coroutine.
156156 * See [CoroutineDispatcher] for the other implementations that are provided by `kotlinx.coroutines`.
157157 *
158+ * When [CoroutineDispatcher] is explicitly specified in the [context], then the new coroutine runs in the context of
159+ * the specified dispatcher while the current thread is blocked. If the specified dispatcher implements [EventLoop]
160+ * interface and this `runBlocking` invocation is performed from inside of the this event loop's thread, then
161+ * this event loop is processed using its [processNextEvent][EventLoop.processNextEvent] method until coroutine completes.
162+ *
158163 * If this blocked thread is interrupted (see [Thread.interrupt]), then the coroutine job is cancelled and
159164 * this `runBlocking` invocation throws [InterruptedException].
160165 *
@@ -166,9 +171,13 @@ public suspend fun <T> run(context: CoroutineContext, block: suspend () -> T): T
166171@Throws(InterruptedException ::class )
167172public fun <T > runBlocking (context : CoroutineContext = EmptyCoroutineContext , block : suspend CoroutineScope .() -> T ): T {
168173 val currentThread = Thread .currentThread()
169- val eventLoop = if (context[ContinuationInterceptor ] == null ) BlockingEventLoop (currentThread) else null
170- val newContext = newCoroutineContext(context + (eventLoop ? : EmptyCoroutineContext ))
171- val coroutine = BlockingCoroutine <T >(newContext, currentThread, privateEventLoop = eventLoop != null )
174+ val contextInterceptor = context[ContinuationInterceptor ]
175+ val privateEventLoop = contextInterceptor == null // create private event loop if no dispatcher is specified
176+ val eventLoop = if (privateEventLoop) BlockingEventLoop (currentThread) else contextInterceptor as ? EventLoop
177+ val newContext = newCoroutineContext(
178+ if (privateEventLoop) context + (eventLoop as ContinuationInterceptor ) else context
179+ )
180+ val coroutine = BlockingCoroutine <T >(newContext, currentThread, eventLoop, privateEventLoop)
172181 coroutine.start(CoroutineStart .DEFAULT , coroutine, block)
173182 return coroutine.joinBlocking()
174183}
@@ -210,10 +219,9 @@ private class RunCompletion<in T>(
210219private class BlockingCoroutine <T >(
211220 parentContext : CoroutineContext ,
212221 private val blockedThread : Thread ,
222+ private val eventLoop : EventLoop ? ,
213223 private val privateEventLoop : Boolean
214224) : AbstractCoroutine<T>(parentContext, true ) {
215- private val eventLoop: EventLoop ? = parentContext[ContinuationInterceptor ] as ? EventLoop
216-
217225 init {
218226 if (privateEventLoop) require(eventLoop is BlockingEventLoop )
219227 }
0 commit comments