1 /*
2  * Copyright 2016-2019 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 and on all interfaces derived from it are **thread-safe** and can
20  * be safely invoked from concurrent coroutines without external synchronization.
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      */
33     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  * Creates a [CompletableDeferred] in an _active_ state.
50  * It is optionally a child of a [parent] job.
51  */
52 @Suppress("FunctionName")
53 public fun <T> CompletableDeferred(parent: Job? = null): CompletableDeferred<T> = CompletableDeferredImpl(parent)
54 
55 /**
56  * Creates an already _completed_ [CompletableDeferred] with a given [value].
57  */
58 @Suppress("FunctionName")
59 public fun <T> CompletableDeferred(value: T): CompletableDeferred<T> = CompletableDeferredImpl<T>(null).apply { complete(value) }
60 
61 /**
62  * Concrete implementation of [CompletableDeferred].
63  */
64 @Suppress("UNCHECKED_CAST")
65 private class CompletableDeferredImpl<T>(
66     parent: Job?
67 ) : JobSupport(true), CompletableDeferred<T>, SelectClause1<T> {
68     init { initParentJobInternal(parent) }
69     override val onCancelComplete get() = true
70     override fun getCompleted(): T = getCompletedInternal() as T
71     override suspend fun await(): T = awaitInternal() as T
72     override val onAwait: SelectClause1<T> get() = this
73     override fun <R> registerSelectClause1(select: SelectInstance<R>, block: suspend (T) -> R) =
74         registerSelectClause1Internal(select, block)
75 
76     override fun complete(value: T): Boolean =
77         makeCompleting(value)
78     override fun completeExceptionally(exception: Throwable): Boolean =
79         makeCompleting(CompletedExceptionally(exception))
80 }
81