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