• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 package kotlinx.coroutines
6 
7 import kotlinx.atomicfu.*
8 import kotlinx.coroutines.internal.*
9 import kotlin.coroutines.*
10 import kotlin.jvm.*
11 
toStatenull12 internal fun <T> Result<T>.toState(
13     onCancellation: ((cause: Throwable) -> Unit)? = null
14 ): Any? = fold(
15     onSuccess = { if (onCancellation != null) CompletedWithCancellation(it, onCancellation) else it },
<lambda>null16     onFailure = { CompletedExceptionally(it) }
17 )
18 
toStatenull19 internal fun <T> Result<T>.toState(caller: CancellableContinuation<*>): Any? = fold(
20     onSuccess = { it },
<lambda>null21     onFailure = { CompletedExceptionally(recoverStackTrace(it, caller)) }
22 )
23 
24 @Suppress("RESULT_CLASS_IN_RETURN_TYPE", "UNCHECKED_CAST")
recoverResultnull25 internal fun <T> recoverResult(state: Any?, uCont: Continuation<T>): Result<T> =
26     if (state is CompletedExceptionally)
27         Result.failure(recoverStackTrace(state.cause, uCont))
28     else
29         Result.success(state as T)
30 
31 internal data class CompletedWithCancellation(
32     @JvmField val result: Any?,
33     @JvmField val onCancellation: (cause: Throwable) -> Unit
34 )
35 
36 /**
37  * Class for an internal state of a job that was cancelled (completed exceptionally).
38  *
39  * @param cause the exceptional completion cause. It's either original exceptional cause
40  *        or artificial [CancellationException] if no cause was provided
41  */
42 internal open class CompletedExceptionally(
43     @JvmField public val cause: Throwable,
44     handled: Boolean = false
45 ) {
46     private val _handled = atomic(handled)
47     val handled: Boolean get() = _handled.value
48     fun makeHandled(): Boolean = _handled.compareAndSet(false, true)
49     override fun toString(): String = "$classSimpleName[$cause]"
50 }
51 
52 /**
53  * A specific subclass of [CompletedExceptionally] for cancelled [AbstractContinuation].
54  *
55  * @param continuation the continuation that was cancelled.
56  * @param cause the exceptional completion cause. If `cause` is null, then a [CancellationException]
57  *        if created on first access to [exception] property.
58  */
59 internal class CancelledContinuation(
60     continuation: Continuation<*>,
61     cause: Throwable?,
62     handled: Boolean
63 ) : CompletedExceptionally(cause ?: CancellationException("Continuation $continuation was cancelled normally"), handled) {
64     private val _resumed = atomic(false)
makeResumednull65     fun makeResumed(): Boolean = _resumed.compareAndSet(false, true)
66 }
67