@@ -4,25 +4,29 @@ import kotlin.coroutines.Continuation
4
4
import kotlin.coroutines.CoroutineContext
5
5
import kotlin.coroutines.EmptyCoroutineContext
6
6
import kotlin.coroutines.startCoroutine
7
- import kotlinx.atomicfu.atomic
7
+ import kotlinx.coroutines.CompletableDeferred
8
8
import kotlinx.coroutines.CoroutineScope
9
+ import kotlinx.coroutines.Deferred
9
10
import kotlinx.coroutines.Dispatchers
11
+ import kotlinx.coroutines.ExperimentalCoroutinesApi
12
+ import kotlinx.coroutines.InternalForInheritanceCoroutinesApi
10
13
import kotlinx.coroutines.Job
14
+ import kotlinx.coroutines.completeWith
11
15
12
16
actual fun <T > runBlockingBenchmark (block : suspend CoroutineScope .() -> T ): T {
13
- val continuation = ContinuationImpl <T >(Dispatchers .Unconfined )
14
- block.startCoroutine(CoroutineScope (continuation.context), continuation)
15
- return continuation.getCompleted()
17
+ val deferred = CompletableContinuation <T >(Dispatchers .Unconfined )
18
+ block.startCoroutine(CoroutineScope (deferred.context), deferred)
19
+ @OptIn(ExperimentalCoroutinesApi ::class )
20
+ return deferred.getCompleted()
16
21
}
17
22
18
- private class ContinuationImpl <T >(context : CoroutineContext = EmptyCoroutineContext ) : Continuation<T> {
19
- private val result = atomic<Result <T >? > (null )
23
+ @OptIn(InternalForInheritanceCoroutinesApi ::class )
24
+ private class CompletableContinuation <T > private constructor(
25
+ context : CoroutineContext ,
26
+ private val deferred : CompletableDeferred <T >,
27
+ ) : Continuation<T>, Deferred<T> by deferred {
28
+ constructor (context: CoroutineContext = EmptyCoroutineContext ) : this (context, CompletableDeferred (context[Job ]))
20
29
21
- override val context: CoroutineContext = context + Job (context[Job ])
22
-
23
- override fun resumeWith (result : Result <T >) {
24
- check(this .result.compareAndSet(null , result)) { " Already resumed, but proposed with update $result " }
25
- }
26
-
27
- fun getCompleted (): T = checkNotNull(result.value) { " The job has not completed yet" }.getOrThrow()
30
+ override val context: CoroutineContext = context + deferred
31
+ override fun resumeWith (result : Result <T >) = check(deferred.completeWith(result)) { " Already resumed" }
28
32
}
0 commit comments