@@ -45,6 +45,9 @@ public abstract class CoroutineDispatcher :
45
45
* potentially forming an event-loop to prevent stack overflows.
46
46
* The event loop is an advanced topic and its implications can be found in [Dispatchers.Unconfined] documentation.
47
47
*
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
+ *
48
51
* A dispatcher can override this method to provide a performance optimization and avoid paying a cost of an unnecessary dispatch.
49
52
* E.g. [MainCoroutineDispatcher.immediate] checks whether we are already in the required UI thread in this method and avoids
50
53
* an additional dispatch when it is not required.
@@ -58,6 +61,9 @@ public abstract class CoroutineDispatcher :
58
61
*
59
62
* This method should generally be exception-safe. An exception thrown from this method
60
63
* may leave the coroutines that use this dispatcher in the inconsistent and hard to debug state.
64
+ *
65
+ * @see dispatch
66
+ * @see Dispatchers.Unconfined
61
67
*/
62
68
public open fun isDispatchNeeded (context : CoroutineContext ): Boolean = true
63
69
@@ -102,18 +108,31 @@ public abstract class CoroutineDispatcher :
102
108
}
103
109
104
110
/* *
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
+ *
106
120
* This method should guarantee that the given [block] will be eventually invoked,
107
121
* 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.
109
123
*
110
124
* 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.
112
133
*
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
117
136
*/
118
137
public abstract fun dispatch (context : CoroutineContext , block : Runnable )
119
138
0 commit comments