@@ -106,17 +106,9 @@ public fun <T> Deferred<T>.asCompletableFuture(): CompletableFuture<T> {
106106}
107107
108108/* *
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.
120112 */
121113public fun <T > CompletionStage<T>.asDeferred (): Deferred <T > {
122114 // Fast path if already completed
@@ -138,26 +130,37 @@ public fun <T> CompletionStage<T>.asDeferred(): Deferred<T> {
138130 result.completeExceptionally(exception)
139131 }
140132 }
133+ if (this is Future <* >) result.cancelFutureOnCompletion(this )
141134 return result
142135}
143136
144137/* *
145138 * Awaits for completion of the future without blocking a thread.
146139 *
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+ *
147149 * This suspending function is cancellable.
148150 * 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].
150152 *
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 .
153155 * 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.
155157 */
156- public suspend fun <T > CompletableFuture <T>.await (): T {
158+ public suspend fun <T > CompletionStage <T>.await (): T {
157159 // fast path when CompletableFuture is already done (does not suspend)
158- if (isDone) {
160+ if (this is Future < * > && isDone() ) {
159161 try {
160- return get()
162+ @Suppress(" UNCHECKED" )
163+ return get() as T
161164 } catch (e: ExecutionException ) {
162165 throw e.cause ? : e // unwrap original cause from ExecutionException
163166 }
0 commit comments