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 * **The `CompletableDeferred` interface is not stable for inheritance in 3rd party libraries**, 20 * as new methods might be added to this interface in the future, but is stable for use. 21 */ 22 public interface CompletableDeferred<T> : Deferred<T> { 23 /** 24 * Completes this deferred value with a given [value]. The result is `true` if this deferred was 25 * completed as a result of this invocation and `false` otherwise (if it was already completed). 26 * 27 * Subsequent invocations of this function have no effect and always produce `false`. 28 * 29 * This function transitions this deferred into _completed_ state if it was not completed or cancelled yet. 30 * However, if this deferred has children, then it transitions into _completing_ state and becomes _complete_ 31 * once all its children are [complete][isCompleted]. See [Job] for details. 32 */ completenull33 public fun complete(value: T): Boolean 34 35 /** 36 * Completes this deferred value exceptionally with a given [exception]. The result is `true` if this deferred was 37 * completed as a result of this invocation and `false` otherwise (if it was already completed). 38 * 39 * Subsequent invocations of this function have no effect and always produce `false`. 40 * 41 * This function transitions this deferred into _cancelled_ state if it was not completed or cancelled yet. 42 * However, that if this deferred has children, then it transitions into _cancelling_ state and becomes _cancelled_ 43 * once all its children are [complete][isCompleted]. See [Job] for details. 44 */ 45 public fun completeExceptionally(exception: Throwable): Boolean 46 } 47 48 /** 49 * Completes this deferred value with the value or exception in the given [result]. Returns `true` if this deferred 50 * was completed as a result of this invocation and `false` otherwise (if it was already completed). 51 * 52 * Subsequent invocations of this function have no effect and always produce `false`. 53 * 54 * This function transitions this deferred in the same ways described by [CompletableDeferred.complete] and 55 * [CompletableDeferred.completeExceptionally]. 56 */ 57 public fun <T> CompletableDeferred<T>.completeWith(result: Result<T>): Boolean = 58 result.fold({ complete(it) }, { completeExceptionally(it) }) 59 60 /** 61 * Creates a [CompletableDeferred] in an _active_ state. 62 * It is optionally a child of a [parent] job. 63 */ 64 @Suppress("FunctionName") CompletableDeferrednull65public fun <T> CompletableDeferred(parent: Job? = null): CompletableDeferred<T> = CompletableDeferredImpl(parent) 66 67 /** 68 * Creates an already _completed_ [CompletableDeferred] with a given [value]. 69 */ 70 @Suppress("FunctionName") 71 public fun <T> CompletableDeferred(value: T): CompletableDeferred<T> = CompletableDeferredImpl<T>(null).apply { complete(value) } 72 73 /** 74 * Concrete implementation of [CompletableDeferred]. 75 */ 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