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