1 @file:Suppress("DEPRECATION_ERROR") 2 3 package kotlinx.coroutines 4 5 import kotlinx.coroutines.selects.* 6 7 /** 8 * A [Deferred] that can be completed via public functions [complete] or [cancel][Job.cancel]. 9 * 10 * Note that the [complete] function returns `false` when this deferred value is already complete or completing, 11 * while [cancel][Job.cancel] returns `true` as long as the deferred is still _cancelling_ and the corresponding 12 * exception is incorporated into the final [completion exception][getCompletionExceptionOrNull]. 13 * 14 * An instance of completable deferred can be created by `CompletableDeferred()` function in _active_ state. 15 * 16 * All functions on this interface are **thread-safe** and can 17 * be safely invoked from concurrent coroutines without external synchronization. 18 */ 19 @OptIn(ExperimentalSubclassOptIn::class) 20 @SubclassOptInRequired(InternalForInheritanceCoroutinesApi::class) 21 public interface CompletableDeferred<T> : Deferred<T> { 22 /** 23 * Completes this deferred value with a given [value]. The result is `true` if this deferred was 24 * completed as a result of this invocation and `false` otherwise (if it was already completed). 25 * 26 * Subsequent invocations of this function have no effect and always produce `false`. 27 * 28 * This function transitions this deferred into _completed_ state if it was not completed or cancelled yet. 29 * However, if this deferred has children, then it transitions into _completing_ state and becomes _complete_ 30 * once all its children are [complete][isCompleted]. See [Job] for details. 31 */ completenull32 public fun complete(value: T): Boolean 33 34 /** 35 * Completes this deferred value exceptionally with a given [exception]. The result is `true` if this deferred was 36 * completed as a result of this invocation and `false` otherwise (if it was already completed). 37 * 38 * Subsequent invocations of this function have no effect and always produce `false`. 39 * 40 * This function transitions this deferred into _cancelled_ state if it was not completed or cancelled yet. 41 * However, that if this deferred has children, then it transitions into _cancelling_ state and becomes _cancelled_ 42 * once all its children are [complete][isCompleted]. See [Job] for details. 43 */ 44 public fun completeExceptionally(exception: Throwable): Boolean 45 } 46 47 /** 48 * Completes this deferred value with the value or exception in the given [result]. Returns `true` if this deferred 49 * was completed as a result of this invocation and `false` otherwise (if it was already completed). 50 * 51 * Subsequent invocations of this function have no effect and always produce `false`. 52 * 53 * This function transitions this deferred in the same ways described by [CompletableDeferred.complete] and 54 * [CompletableDeferred.completeExceptionally]. 55 */ 56 public fun <T> CompletableDeferred<T>.completeWith(result: Result<T>): Boolean = 57 result.fold({ complete(it) }, { completeExceptionally(it) }) 58 59 /** 60 * Creates a [CompletableDeferred] in an _active_ state. 61 * It is optionally a child of a [parent] job. 62 */ 63 @Suppress("FunctionName") CompletableDeferrednull64public fun <T> CompletableDeferred(parent: Job? = null): CompletableDeferred<T> = CompletableDeferredImpl(parent) 65 66 /** 67 * Creates an already _completed_ [CompletableDeferred] with a given [value]. 68 */ 69 @Suppress("FunctionName") 70 public fun <T> CompletableDeferred(value: T): CompletableDeferred<T> = CompletableDeferredImpl<T>(null).apply { complete(value) } 71 72 /** 73 * Concrete implementation of [CompletableDeferred]. 74 */ 75 @OptIn(InternalForInheritanceCoroutinesApi::class) 76 @Suppress("UNCHECKED_CAST") 77 private class CompletableDeferredImpl<T>( 78 parent: Job? 79 ) : JobSupport(true), CompletableDeferred<T> { 80 init { initParentJob(parent) } 81 override val onCancelComplete get() = true getCompletednull82 override fun getCompleted(): T = getCompletedInternal() as T 83 override suspend fun await(): T = awaitInternal() as T 84 override val onAwait: SelectClause1<T> get() = onAwaitInternal as SelectClause1<T> 85 86 override fun complete(value: T): Boolean = 87 makeCompleting(value) 88 override fun completeExceptionally(exception: Throwable): Boolean = 89 makeCompleting(CompletedExceptionally(exception)) 90 } 91