blob: f0d3de2802ad0714790544960b97c861994ed890 [file] [log] [blame]
/*
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package kotlinx.coroutines.experimental
import kotlin.coroutines.experimental.*
import kotlin.coroutines.experimental.intrinsics.*
/**
* Yields a thread (or thread pool) of the current coroutine dispatcher to other coroutines to run.
* If the coroutine dispatcher does not have its own thread pool (like [Dispatchers.Unconfined]) then this
* function does nothing, but checks if the coroutine [Job] was completed.
* This suspending function is cancellable.
* If the [Job] of the current coroutine is cancelled or completed when this suspending function is invoked or while
* this function is waiting for dispatching, it resumes with [CancellationException].
*/
public suspend fun yield(): Unit = suspendCoroutineUninterceptedOrReturn sc@ { uCont ->
val context = uCont.context
context.checkCompletion()
val cont = uCont.intercepted() as? DispatchedContinuation<Unit> ?: return@sc Unit
if (!cont.dispatcher.isDispatchNeeded(context)) return@sc Unit
cont.dispatchYield(Unit)
COROUTINE_SUSPENDED
}
internal fun CoroutineContext.checkCompletion() {
val job = get(Job)
if (job != null && !job.isActive) throw job.getCancellationException()
}