@@ -106,17 +106,9 @@ public fun <T> Deferred<T>.asCompletableFuture(): CompletableFuture<T> {
106
106
}
107
107
108
108
/* *
109
- * Awaits for completion of the completion stage without blocking a thread.
110
- *
111
- * This suspending function is not cancellable, because there is no way to cancel a `CompletionStage`.
112
- * Use `CompletableFuture.await()` for cancellable wait.
113
- */
114
- public suspend fun <T > CompletionStage<T>.await (): T = suspendCoroutine { cont: Continuation <T > ->
115
- whenComplete(ContinuationConsumer (cont))
116
- }
117
-
118
- /* *
119
- * Converts this future to an instance of [Deferred].
109
+ * Converts this completion stage to an instance of [Deferred].
110
+ * When this completion stage is an instance of [Future], then it is cancelled when
111
+ * the resulting deferred is cancelled.
120
112
*/
121
113
public fun <T > CompletionStage<T>.asDeferred (): Deferred <T > {
122
114
// Fast path if already completed
@@ -138,26 +130,37 @@ public fun <T> CompletionStage<T>.asDeferred(): Deferred<T> {
138
130
result.completeExceptionally(exception)
139
131
}
140
132
}
133
+ if (this is Future <* >) result.cancelFutureOnCompletion(this )
141
134
return result
142
135
}
143
136
144
137
/* *
145
138
* Awaits for completion of the future without blocking a thread.
146
139
*
140
+ * @suppress **Deprecated**: For binary compatibility only
141
+ */
142
+ @Deprecated(" For binary compatibility only" , level = DeprecationLevel .HIDDEN )
143
+ public suspend fun <T > CompletableFuture<T>.await (): T =
144
+ (this as CompletionStage <T >).await()
145
+
146
+ /* *
147
+ * Awaits for completion of the completion stage without blocking a thread.
148
+ *
147
149
* This suspending function is cancellable.
148
150
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
149
- * stops waiting for the future and immediately resumes with [CancellationException].
151
+ * stops waiting for the completion stage and immediately resumes with [CancellationException].
150
152
*
151
- * Note, that `CompletableFuture` does not support prompt removal of installed listeners, so on cancellation of this wait
152
- * a few small objects will remain in the `CompletableFuture ` stack of completion actions until the future completes.
153
+ * Note, that `CompletionStage` implementation does not support prompt removal of installed listeners, so on cancellation of this wait
154
+ * a few small objects will remain in the `CompletionStage ` stack of completion actions until it completes itself .
153
155
* However, the care is taken to clear the reference to the waiting coroutine itself, so that its memory can be
154
- * released even if the future never completes.
156
+ * released even if the completion stage never completes.
155
157
*/
156
- public suspend fun <T > CompletableFuture <T>.await (): T {
158
+ public suspend fun <T > CompletionStage <T>.await (): T {
157
159
// fast path when CompletableFuture is already done (does not suspend)
158
- if (isDone) {
160
+ if (this is Future < * > && isDone() ) {
159
161
try {
160
- return get()
162
+ @Suppress(" UNCHECKED" )
163
+ return get() as T
161
164
} catch (e: ExecutionException ) {
162
165
throw e.cause ? : e // unwrap original cause from ExecutionException
163
166
}
0 commit comments