1 /*
2 * Copyright 2016-2020 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")
CompletableDeferrednull68 public 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>, SelectClause1<T> {
83 init { initParentJobInternal(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() = this
88 override fun <R> registerSelectClause1(select: SelectInstance<R>, block: suspend (T) -> R) =
89 registerSelectClause1Internal(select, block)
90
91 override fun complete(value: T): Boolean =
92 makeCompleting(value)
93 override fun completeExceptionally(exception: Throwable): Boolean =
94 makeCompleting(CompletedExceptionally(exception))
95 }
96