1 /* 2 * Copyright 2016-2018 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 kotlin.coroutines.* 8 import kotlin.coroutines.intrinsics.* 9 10 @PublishedApi internal const val MODE_ATOMIC_DEFAULT = 0 // schedule non-cancellable dispatch for suspendCoroutine 11 @PublishedApi internal const val MODE_CANCELLABLE = 1 // schedule cancellable dispatch for suspendCancellableCoroutine 12 @PublishedApi internal const val MODE_DIRECT = 2 // when the context is right just invoke the delegate continuation direct 13 @PublishedApi internal const val MODE_UNDISPATCHED = 3 // when the thread is right, but need to mark it with current coroutine 14 @PublishedApi internal const val MODE_IGNORE = 4 // don't do anything 15 16 internal val Int.isCancellableMode get() = this == MODE_CANCELLABLE 17 internal val Int.isDispatchedMode get() = this == MODE_ATOMIC_DEFAULT || this == MODE_CANCELLABLE 18 19 internal fun <T> Continuation<T>.resumeMode(value: T, mode: Int) { 20 when (mode) { 21 MODE_ATOMIC_DEFAULT -> resume(value) 22 MODE_CANCELLABLE -> resumeCancellable(value) 23 MODE_DIRECT -> resumeDirect(value) 24 MODE_UNDISPATCHED -> (this as DispatchedContinuation).resumeUndispatched(value) 25 MODE_IGNORE -> {} 26 else -> error("Invalid mode $mode") 27 } 28 } 29 30 internal fun <T> Continuation<T>.resumeWithExceptionMode(exception: Throwable, mode: Int) { 31 when (mode) { 32 MODE_ATOMIC_DEFAULT -> resumeWithException(exception) 33 MODE_CANCELLABLE -> resumeCancellableWithException(exception) 34 MODE_DIRECT -> resumeDirectWithException(exception) 35 MODE_UNDISPATCHED -> (this as DispatchedContinuation).resumeUndispatchedWithException(exception) 36 MODE_IGNORE -> {} 37 else -> error("Invalid mode $mode") 38 } 39 } 40 41 internal fun <T> Continuation<T>.resumeUninterceptedMode(value: T, mode: Int) { 42 when (mode) { 43 MODE_ATOMIC_DEFAULT -> intercepted().resume(value) 44 MODE_CANCELLABLE -> intercepted().resumeCancellable(value) 45 MODE_DIRECT -> resume(value) 46 MODE_UNDISPATCHED -> withCoroutineContext(context, null) { resume(value) } 47 MODE_IGNORE -> {} 48 else -> error("Invalid mode $mode") 49 } 50 } 51 52 internal fun <T> Continuation<T>.resumeUninterceptedWithExceptionMode(exception: Throwable, mode: Int) { 53 when (mode) { 54 MODE_ATOMIC_DEFAULT -> intercepted().resumeWithException(exception) 55 MODE_CANCELLABLE -> intercepted().resumeCancellableWithException(exception) 56 MODE_DIRECT -> resumeWithException(exception) 57 MODE_UNDISPATCHED -> withCoroutineContext(context, null) { resumeWithException(exception) } 58 MODE_IGNORE -> {} 59 else -> error("Invalid mode $mode") 60 } 61 } 62