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")
CompletableDeferrednull65 public 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