@@ -45,6 +45,9 @@ public abstract class CoroutineDispatcher :
4545 * potentially forming an event-loop to prevent stack overflows.
4646 * The event loop is an advanced topic and its implications can be found in [Dispatchers.Unconfined] documentation.
4747 *
48+ * The [context] parameter represents the context of the coroutine that is being dispatched,
49+ * or [EmptyCoroutineContext] if a non-coroutine-specific [Runnable] is dispatched instead.
50+ *
4851 * A dispatcher can override this method to provide a performance optimization and avoid paying a cost of an unnecessary dispatch.
4952 * E.g. [MainCoroutineDispatcher.immediate] checks whether we are already in the required UI thread in this method and avoids
5053 * an additional dispatch when it is not required.
@@ -58,6 +61,9 @@ public abstract class CoroutineDispatcher :
5861 *
5962 * This method should generally be exception-safe. An exception thrown from this method
6063 * may leave the coroutines that use this dispatcher in the inconsistent and hard to debug state.
64+ *
65+ * @see dispatch
66+ * @see Dispatchers.Unconfined
6167 */
6268 public open fun isDispatchNeeded (context : CoroutineContext ): Boolean = true
6369
@@ -102,18 +108,31 @@ public abstract class CoroutineDispatcher :
102108 }
103109
104110 /* *
105- * Dispatches execution of a runnable [block] onto another thread in the given [context].
111+ * Requests execution of a runnable [block].
112+ * The dispatcher guarantees that [block] will eventually execute, typically by dispatching it to a thread pool,
113+ * using a dedicated thread, or just executing the block in place.
114+ * The [context] parameter represents the context of the coroutine that is being dispatched,
115+ * or [EmptyCoroutineContext] if a non-coroutine-specific [Runnable] is dispatched instead.
116+ * Implementations may use [context] for additional context-specific information,
117+ * such as priority, whether the dispatched coroutine can be invoked in place,
118+ * coroutine name, and additional diagnostic elements.
119+ *
106120 * This method should guarantee that the given [block] will be eventually invoked,
107121 * otherwise the system may reach a deadlock state and never leave it.
108- * Cancellation mechanism is transparent for [CoroutineDispatcher] and is managed by [block] internals.
122+ * The cancellation mechanism is transparent for [CoroutineDispatcher] and is managed by [block] internals.
109123 *
110124 * This method should generally be exception-safe. An exception thrown from this method
111- * may leave the coroutines that use this dispatcher in the inconsistent and hard to debug state.
125+ * may leave the coroutines that use this dispatcher in an inconsistent and hard-to-debug state.
126+ *
127+ * This method must not immediately call [block]. Doing so may result in `StackOverflowError`
128+ * when `dispatch` is invoked repeatedly, for example when [yield] is called in a loop.
129+ * In order to execute a block in place, it is required to return `false` from [isDispatchNeeded]
130+ * and delegate the `dispatch` implementation to `Dispatchers.Unconfined.dispatch` in such cases.
131+ * To support this, the coroutines machinery ensures in-place execution and forms an event-loop to
132+ * avoid unbound recursion.
112133 *
113- * This method must not immediately call [block]. Doing so would result in [StackOverflowError]
114- * when [yield] is repeatedly called from a loop. However, an implementation that returns `false` from
115- * [isDispatchNeeded] can delegate this function to `dispatch` method of [Dispatchers.Unconfined], which is
116- * integrated with [yield] to avoid this problem.
134+ * @see isDispatchNeeded
135+ * @see Dispatchers.Unconfined
117136 */
118137 public abstract fun dispatch (context : CoroutineContext , block : Runnable )
119138
0 commit comments