Skip to content

withContext ingnores cancellation from withTimeout when the dispatcher cannot execute the body #4382

Open
@zuevmaxim

Description

@zuevmaxim

Describe the bug

The following code hangs, while I expected it to output Timeout. When I uncomment the commented code, it works as I expected, so withContext handles timeouts differently. I wonder if it can be handled correctly without a deadlock here.

Provide a Reproducer

package kt.coroutines

import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import java.util.concurrent.Executors
import kotlin.coroutines.resume

fun main() {
    val executor = Executors.newSingleThreadExecutor { r -> Thread(r, "MyThread") }
    val dispatcher = executor.asCoroutineDispatcher()
    runBlocking(dispatcher) {
        runBlocking { // block on the dispatcher thread
            val c = Channel<String>()
            launch(Dispatchers.Default) {
                try {
                    withTimeout(1000) {
//                        suspendCancellableCoroutine { cont ->
//                            executor.submit {
//                                c.trySend("Switched to dispatcher")
//                                cont.resume(Unit)
//                            }
//                        }
                        withContext(dispatcher) { // cannot switch to dispatcher as it is locked, but can it timeout?
                            c.send("Switched to dispatcher")
                        }
                    }
                } catch (_: TimeoutCancellationException) {
                    c.send("Timeout")
                }
            }
            println(c.receive())
        }
    }
    executor.shutdown()
}

version 1.9.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions