blob: 014f55573116b9bf63100a2a380894741019e1e7 [file] [log] [blame]
Roman Elizarovf16fd272017-02-07 11:26:00 +03001/*
2 * Copyright 2016-2017 JetBrains s.r.o.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Roman Elizarovd528e3e2017-01-23 15:40:05 +030017package kotlinx.coroutines.experimental
18
Roman Elizarov1216e912017-02-22 09:57:06 +030019import kotlin.coroutines.experimental.intrinsics.COROUTINE_SUSPENDED
20import kotlin.coroutines.experimental.intrinsics.suspendCoroutineOrReturn
21
Roman Elizarovd528e3e2017-01-23 15:40:05 +030022/**
23 * Yields a thread (or thread pool) of the current coroutine dispatcher to other coroutines to run.
Roman Elizarov2f6d7c92017-02-03 15:16:07 +030024 * If the coroutine dispatcher does not have its own thread pool (like [Unconfined] dispatcher) then this
Roman Elizarove727cee2017-01-31 09:20:36 +030025 * function does nothing, but checks if the coroutine [Job] was completed.
Roman Elizarovd528e3e2017-01-23 15:40:05 +030026 * This suspending function is cancellable.
Roman Elizarove727cee2017-01-31 09:20:36 +030027 * If the [Job] of the current coroutine is completed when this suspending function is invoked or while
28 * this function is waiting for dispatching, it resumes with [CancellationException].
Roman Elizarovd528e3e2017-01-23 15:40:05 +030029 */
Roman Elizarov1216e912017-02-22 09:57:06 +030030suspend fun yield(): Unit = suspendCoroutineOrReturn sc@ { cont ->
31 val context = cont.context
32 val job = context[Job]
33 if (job != null && job.isCompleted) throw job.getCompletionException()
34 if (cont !is DispatchedContinuation<Unit>) return@sc Unit
35 if (!cont.dispatcher.isDispatchNeeded(context)) return@sc Unit
36 cont.dispatchYield(job, Unit)
37 COROUTINE_SUSPENDED
Roman Elizarovd528e3e2017-01-23 15:40:05 +030038}