[issue43523] Handling Ctrl+C while waiting on I/O in Windows

Eryk Sun report at bugs.python.org
Tue Mar 16 19:52:56 EDT 2021


Eryk Sun <eryksun at gmail.com> added the comment:

winrshost.exe runs Python with its standard I/O redirected to pipes, so sys.stdin.read(1) blocks the main thread while waiting for the synchronous read to complete. If the user types something, then the read completes and the main thread can call the SIGINT handler, which raises KeyboardInterrupt.

By default, SIGBREAK is not handled, so the console CTRL_BREAK_EVENT executes the default handler on the control thread, which calls ExitProcess(STATUS_CONTROL_C_EXIT).

Currently, the only I/O that can be interrupted is reading from console input, since the console itself cancels the request when the user presses Ctrl+C.

To interrupt synchronous I/O in general, the C signal handler could call WinAPI CancelSynchronousIo() with a handle for the main thread. Synchronous I/O calls would have to be updated to handle ERROR_OPERATION_ABORTED (from C _doserrno if calling C read/write). This entails calling PyErr_CheckSignals() in order to call the registered signal handler and return whether it raises an exception. But first PyOS_InterruptOccurred() has to be checked. If SIGINT isn't tripped, the abort request didn't originate from the signal handler, so the call should fail without calling PyErr_CheckSignals().

An asynchronous I/O request (e.g. socket I/O is typically asynchronous) can be canceled with CancelIo[Ex], which requires a handle for the open file that has the pending request. This case can only be addressed by the C signal handler if the main thread registers the file handle with the signal module before waiting for I/O completion. If a wait for I/O completion is alertable, then a user-mode APC can be queued to the thread in order to call CancelIo() on the file handle. If it's not an alertable wait, then the I/O request can be canceled with CancelIoEx(), but preferably the OVERLAPPED record for the request should also be registered, else all of the file's pending I/O requests will be canceled, instead of canceling only the request that's blocking the main thread.

----------
components: +IO, Interpreter Core, Windows
nosy: +eryksun, paul.moore, steve.dower, tim.golden, zach.ware
title: Handling Ctrl+C when waiting on stdin on Windows via winrs -> Handling Ctrl+C while waiting on I/O in Windows
type:  -> enhancement
versions: +Python 3.10, Python 3.8

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue43523>
_______________________________________


More information about the Python-bugs-list mailing list