File tree Expand file tree Collapse file tree 5 files changed +23
-8
lines changed
kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental
kotlinx-coroutines-jdk8/src/main/kotlin/kotlinx/coroutines/experimental/future Expand file tree Collapse file tree 5 files changed +23
-8
lines changed Original file line number Diff line number Diff line change @@ -59,7 +59,7 @@ private class StandaloneCoroutine(
59
59
val parentContext : CoroutineContext
60
60
) : JobContinuation<Unit>(parentContext) {
61
61
override fun afterCompletion (state : Any? , closeException : Throwable ? ) {
62
- if (closeException != null ) handleCoroutineException(context, closeException)
62
+ super .afterCompletion(state, closeException) // handle closeException
63
63
// note the use of the parent context below!
64
64
if (state is CompletedExceptionally ) handleCoroutineException(parentContext, state.exception)
65
65
}
@@ -69,7 +69,7 @@ private class BlockingCoroutine<T>(parentContext: CoroutineContext) : JobContinu
69
69
val blockedThread: Thread = Thread .currentThread()
70
70
71
71
override fun afterCompletion (state : Any? , closeException : Throwable ? ) {
72
- if (closeException != null ) handleCoroutineException(context, closeException)
72
+ super .afterCompletion(state, closeException) // handle closeException
73
73
LockSupport .unpark(blockedThread)
74
74
}
75
75
Original file line number Diff line number Diff line change @@ -47,7 +47,7 @@ internal class SafeCancellableContinuation<in T>(
47
47
48
48
@Suppress(" UNCHECKED_CAST" )
49
49
override fun afterCompletion (state : Any? , closeException : Throwable ? ) {
50
- if (closeException != null ) handleCoroutineException(context, closeException)
50
+ super .afterCompletion(state, closeException) // handle closeException
51
51
if (suspendedThread == = Thread .currentThread()) {
52
52
// cancelled during suspendCancellableCoroutine in its thread
53
53
suspendedThread = null
Original file line number Diff line number Diff line change @@ -12,9 +12,17 @@ public interface Deferred<out T> : Job {
12
12
* Awaits for completion of this value without blocking a thread and resumes when deferred computation is complete.
13
13
* This suspending function is cancellable.
14
14
* If the [Job] of the current coroutine is completed while this suspending function is waiting, this function
15
- * immediately resumes with [CancellationException] .
15
+ * immediately resumes with [CancellationException].
16
16
*/
17
17
public suspend fun await (): T
18
+
19
+ /* *
20
+ * Returns *completed* result or throws [IllegalStateException] if this deferred value is still [isActive].
21
+ * It throws the corresponding exception if this deferred has completed exceptionally.
22
+ * This function is designed to be used from [onCompletion] handlers, when there is an absolute certainty that
23
+ * the value is already complete.
24
+ */
25
+ public fun getCompleted (): T
18
26
}
19
27
20
28
/* *
@@ -54,7 +62,11 @@ private class DeferredCoroutine<T>(
54
62
})
55
63
}
56
64
57
- override fun afterCompletion (state : Any? , closeException : Throwable ? ) {
58
- if (closeException != null ) handleCoroutineException(context, closeException)
65
+ @Suppress(" UNCHECKED_CAST" )
66
+ override fun getCompleted (): T {
67
+ val state = getState()
68
+ check(state !is Active ) { " This deferred value is still active" }
69
+ if (state is CompletedExceptionally ) throw state.exception
70
+ return state as T
59
71
}
60
72
}
Original file line number Diff line number Diff line change @@ -35,4 +35,8 @@ internal open class JobContinuation<in T>(
35
35
}
36
36
}
37
37
}
38
+
39
+ override fun afterCompletion (state : Any? , closeException : Throwable ? ) {
40
+ if (closeException != null ) handleCoroutineException(context, closeException)
41
+ }
38
42
}
Original file line number Diff line number Diff line change @@ -35,9 +35,8 @@ public fun <T> Deferred<T>.toCompletableFuture(): CompletableFuture<T> {
35
35
val future = CompletableFuture <T >()
36
36
future.whenComplete { _, exception -> cancel(exception) }
37
37
onCompletion {
38
- // todo: write better (more efficient) implementation, because we know that await will not suspend
39
38
try {
40
- future.complete(runBlocking( Job () + Here ) { await() } )
39
+ future.complete(getCompleted() )
41
40
} catch (exception: Exception ) {
42
41
future.completeExceptionally(exception)
43
42
}
You can’t perform that action at this time.
0 commit comments