[issue23237] Interrupts are lost during readline PyOS_InputHook processing (reopening)

Michiel de Hoon report at bugs.python.org
Sat May 30 08:35:07 CEST 2015


Michiel de Hoon added the comment:

Vadmium, thank you for carefully looking at this patch.

Polling PyErr_CheckSignals() directly in the tkinter EventHook loop works in the #if defined(WITH_THREAD) || defined(MS_WINDOWS) block, as there Tcl_DoOneEvent(TCL_DONT_WAIT) exits immediately.

However in the #else block Tcl_DoOneEvent(0) is called. Here, Tcl_DoOneEvent does not return until there is some event. So if a user presses Ctrl-C, then trip_signal in Modules/signalmodule.c does get called, but Tcl_DoOneEvent won't know about it and will continue to wait for an event. The KeyboardInterrupt will then happen only after the user presses enter or moves the mouse over the Tk window.

That said, now I realize that my patch doesn't solve that problem either. So I need to go back and think of a proper way to exit Tcl_DoOneEvent in case of an interrupt. I think that that is a sufficiently complex problem to warrant its own patch. For the current patch, I suggest we consider the changes to Modules/readline.c and Parser/myreadline.c only, and leave out any changes to Modules/_tkinter.c.

In response to your comments on Modules/readline.c:

>Modules/readline.c:998:
> if(PyOS_InputHook) has_input = PyOS_InputHook();
> This contradicts the documentation, which says
> PyIO_InputHook()’s return value is ignored

Yes you are correct; the documentation will have to be updated if we start using the return value of PyOS_InputHook().

My proposal to use return value == -1 and errno == EINTR to indicate interrupts is based on the convention for select(). In extension modules such as Tkinter, PyOS_InputHook points to a function that returns if input is available on stdin, so effectively it's like a simplified version of select() that only looks at stdin.

In Tkinter, pygtk, and PyQT, PyOS_InputHook returns 0; in matplotlib's MacOSX backend it returns +1. So I think it is safe to start using -1 for interrupts.
But yes, the documentation will have to be updated.

>Modules/readline.c:1065:
> old_timeout = rl_set_keyboard_input_timeout(0);
> Won’t this poll PyOS_InputHook over and over, wasting CPU time?
No it won't. In well-designed code (including Tkinter, pygtk, PyQT, and matplotlib's MacOSX backend) PyOS_InputHook does not return until there is some activity on stdin, and therefore PyOS_InputHook does not get called repetitively anyway. So the timeout is only relevant as the delay until readline() calls PyOS_InputHook(). Since there is no point to this delay, it's better to set it to zero.

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue23237>
_______________________________________


More information about the Python-bugs-list mailing list