blob: ff53e06d987c275d4cc7b9655c370155fd38d79c [file] [log] [blame]
Roman Elizarov44e3ba52017-08-01 22:01:31 -07001/*
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
17/*
18 * Copyright 2016-2017 JetBrains s.r.o.
19 *
20 * Licensed under the Apache License, Version 2.0 (the "License");
21 * you may not use this file except in compliance with the License.
22 * You may obtain a copy of the License at
23 *
24 * http://www.apache.org/licenses/LICENSE-2.0
25 *
26 * Unless required by applicable law or agreed to in writing, software
27 * distributed under the License is distributed on an "AS IS" BASIS,
28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29 * See the License for the specific language governing permissions and
30 * limitations under the License.
31 */
32
33package kotlinx.coroutines.experimental.quasar
34
35import co.paralleluniverse.fibers.Fiber
36import co.paralleluniverse.fibers.FiberAsync
37import co.paralleluniverse.fibers.SuspendExecution
38import co.paralleluniverse.fibers.Suspendable
39import co.paralleluniverse.strands.SuspendableCallable
Vsevolod Tolstopyatov80a29472018-04-17 16:02:02 +030040import kotlinx.coroutines.experimental.*
Roman Elizarov44e3ba52017-08-01 22:01:31 -070041import kotlin.coroutines.experimental.Continuation
42import kotlin.coroutines.experimental.CoroutineContext
43import kotlin.coroutines.experimental.startCoroutine
44
45/**
46 * Runs Quasar-instrumented suspendable code from Kotlin coroutine.
47 */
48suspend fun <T> runSuspendable(callable: SuspendableCallable<T>): T = suspendCancellableCoroutine { cont ->
49 val fiber = object : Fiber<Unit>() {
50 @Throws(SuspendExecution::class)
51 override fun run() {
52 val result = try { callable.run() }
53 catch (e: Throwable) {
54 cont.resumeWithException(e)
55 return
56 }
57 cont.resume(result)
58 }
59 }
Vsevolod Tolstopyatov80a29472018-04-17 16:02:02 +030060 cont.cancelFutureOnCancellation(fiber)
Roman Elizarov44e3ba52017-08-01 22:01:31 -070061 fiber.start()
62}
63
64/**
65 * Runs Kotlin suspending function from Quasar-instrumented suspendable code.
66 */
67@Suspendable
68fun <T> runFiberBlocking(block: suspend () -> T): T =
69 CoroutineAsync(block).run()
70
71private class CoroutineAsync<T>(
72 private val block: suspend () -> T
73) : FiberAsync<T, Throwable>(), Continuation<T> {
74 override val context: CoroutineContext = Fiber.currentFiber().scheduler.executor.asCoroutineDispatcher()
75 override fun resume(value: T) { asyncCompleted(value) }
76 override fun resumeWithException(exception: Throwable) { asyncFailed(exception) }
77
78 override fun requestAsync() {
79 block.startCoroutine(completion = this)
80 }
81}