Skip to content

asyncio functions raising KeyboardInterrupt/SystemExit can produce a deadlock #118

Open
@oremanj

Description

@oremanj

asyncio contains a number of special-cases where KeyboardInterrupt and SystemExit are handled differently than other exceptions: they are allowed to propagate out of the event loop, rather than (or in some cases in addition to) being set as the result of a future or passed to the default_exception_handler. Presumably this was done as an ugly-but-practical solution to the endless stream of "asyncio hangs when you press Ctrl-C!" bugs.

trio_asyncio does not deal well with the event loop raising an exception without resolving all its futures. In some other part of the program, there is a call to run_aio_future which is uninterruptibly waiting to see what that future resolves to. If the event loop exits, the future will never be resolved. Boom, deadlock.

This isn't much of a problem with actual keyboard interrupts, because we can (mostly) route those using restrict_keyboard_interrupt_to_checkpoints so they aren't raised within asyncio-flavored code. But it definitely breaks code that uses KeyboardInterrupt as a normal signaling exception. I ran into this when using prompt_toolkit; by default it produces a KeyboardInterrupt exception when it reads Ctrl+C from the terminal (the terminal is in raw mode so this doesn't produce a SIGINT). Under trio_asyncio such a Ctrl+C can produce a deadlock instead.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions