You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reproducer from #407 will fail with exception in coroutines machinery
@Test
fun testCancelProduce() = runTest {
val source = Channel<Int>()
val produced = produce<Int>(ctx, onCompletion = source.consumes()) {
source.receive() // <- when exception is thrown from here, source is NOT empty for Unconfined
}
produced.cancel()
}
Behaviour will be different for Unconfined and coroutineContext as ctx.
It's because we do the following:
cont.cancel(e)
-> dispatch() { cont.resumeWithException(e) }
-> for (handler in handler) handler.invoke(e)
We have data-race with small window between dispatched continuation and handlers invocation. Same race is 100% reproducible with Unconfined.
The text was updated successfully, but these errors were encountered:
1) Invoke handlers before dispatching in CancellableContinuation to make behaviour timing-independent and Unconfined doesn't produce unexpected results
2) Invoke onCancellation -> handlers -> onCompletion in Job to make behaviour timing-independent
Fixes#415
Reproducer from #407 will fail with exception in coroutines machinery
Behaviour will be different for
Unconfined
andcoroutineContext
asctx
.It's because we do the following:
We have data-race with small window between dispatched continuation and handlers invocation. Same race is 100% reproducible with Unconfined.
The text was updated successfully, but these errors were encountered: