blob: 803c9c9e93a8ffeb5c9134313ae047bffe54b907 [file] [log] [blame]
Roman Elizarovd528e3e2017-01-23 15:40:05 +03001package kotlinx.coroutines.experimental
2
3import kotlin.coroutines.ContinuationInterceptor
4
5/**
6 * This dispatcher _feature_ is implemented by [CoroutineDispatcher] implementations that
Roman Elizarov67891d82017-01-23 16:47:20 +03007 * natively support [yield] function. It shall be implemented only by [CoroutineDispatcher]
8 * classes with non-trivial [CoroutineDispatcher.isDispatchNeeded] implementations.
Roman Elizarovd528e3e2017-01-23 15:40:05 +03009 */
10public interface Yield {
11 /**
12 * Yields a thread (or thread pool) of this dispatcher to other coroutines to run.
13 * This suspending function is cancellable.
14 * If the [Job] of the current coroutine is completed while this suspending function is suspended, this function
15 * resumes with [CancellationException].
16 */
17 suspend fun yield(): Unit = suspendCancellableCoroutine { cont -> scheduleResume(cont) }
18
19 /**
20 * Schedules resume of a specified [continuation] in this dispatcher's thread (or pool of threads).
21 */
22 fun scheduleResume(continuation: CancellableContinuation<Unit>)
23}
24
25/**
26 * Yields a thread (or thread pool) of the current coroutine dispatcher to other coroutines to run.
27 * If the coroutine dispatcher does not have its own thread pool (like [Here] dispatcher) and does not implement
28 * [Yield], then the [Yield] implementation is taken from the context, if there is none, then this
29 * function does nothing, but checks if the coroutine [Job] was cancelled.
30 * This suspending function is cancellable.
31 * If the [Job] of the current coroutine is completed while this suspending function is suspended, this function
32 * resumes with [CancellationException].
33 */
34suspend fun yield(): Unit = suspendCancellableCoroutine sc@ { cont ->
35 (cont.context[ContinuationInterceptor] as? Yield)?.apply {
36 scheduleResume(cont)
37 return@sc
38 }
39 cont.resume(Unit)
40}