• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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")
CompletableDeferrednull64 public 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