Fix improper handling of coroutine interceptors
Don't use coroutine facade in following cases: * When calling coroutine functions in non-suspend mode (i.e. suspend flag is either false or skipped). * When passing continuation from suspend function to suspend function. Use facade only for corresponding intrinsics. Reason: interceptor should not be called on each suspend function invocation, it should be called after resume from innermost suspend function. Fix KT-17067. The example provided with the issue is very similar to dispatchResume.kt which passes after these changes. Add test to prove that KT-17446 is no more reproducible.
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
import kotlin.coroutines.experimental.*
|
||||
import kotlin.coroutines.experimental.intrinsics.suspendCoroutineOrReturn
|
||||
import kotlin.coroutines.experimental.intrinsics.COROUTINE_SUSPENDED
|
||||
|
||||
fun box(): String {
|
||||
async {
|
||||
log += "1;"
|
||||
wait()
|
||||
log += "2;"
|
||||
}
|
||||
|
||||
while (postponed != null) {
|
||||
log += "suspended;"
|
||||
postponed!!()
|
||||
}
|
||||
|
||||
if (log != "1;wait2;suspended;wait;suspended;2;") return "fail: $log"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun async(f: suspend () -> Unit) {
|
||||
f.startCoroutine(handleResultContinuation {
|
||||
postponed = null
|
||||
})
|
||||
}
|
||||
|
||||
suspend fun wait(): Unit {
|
||||
wait2()
|
||||
log += "wait;"
|
||||
return suspendCoroutineOrReturn { c ->
|
||||
postponed = { c.resume(Unit) }
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun wait2(): Unit = suspendCoroutineOrReturn { c ->
|
||||
log += "wait2;"
|
||||
postponed = { c.resume(Unit) }
|
||||
COROUTINE_SUSPENDED
|
||||
}
|
||||
|
||||
var postponed: (() -> Unit)? = { }
|
||||
|
||||
var log = ""
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
import kotlin.coroutines.experimental.*
|
||||
|
||||
Reference in New Issue
Block a user