Author spiv
Recipients spiv
Date 2010-04-09.06:50:32
SpamBayes Score 3.39045e-12
Marked as misclassified No
Message-id <1270795837.87.0.683673992087.issue8354@psf.upfronthosting.co.za>
In-reply-to
Content
The effect of signal.siginterrupt(somesig, False) is reset the first time a that signal is received.  This is not the documented behaviour, and I do not think this is a desireable behaviour.  It renders siginterrupt effectively useless at providing the robustness against EINTR it is intended to provide.

Attached is a fairly simple program to show this using SIGWINCH: run it in a resizeable terminal, and resize it twice.  Notice that on the second terminal resize (i.e. the second SIGWINCH signal) the program crashes with an EINTR from the os.read.

A partial workaround for the problem is to call signal.siginterrupt(somesig, False) again inside your signal handler, but it's very fragile.  It depends on Python getting a chance to run the Python function registered by the signal.signal call, but this is not guaranteed.  If there's frequent IO, that workaround might suffice.  For the sig-test.py example attached to this bug, it doesn't (try it).

The cause seems to be that signal_handler in signalmodule.c unconditionally does PyOS_setsig(sig_num, signal_handler) [except for SIGCHLD], which unconditionally invokes siginterrupt(sig, 1).  A possible fix would be to add a 'int siginterrupt_flag;' to the Handlers array, and arrange for that value to be passed instead of the hard-coded 1.  Another might be to not call PyOS_setsig from signal_handler at all -- I'm not sure why it is trying to reinstall itself, but perhaps there's some issue there I'm not aware of.
History
Date User Action Args
2010-04-09 06:50:37spivsetrecipients: + spiv
2010-04-09 06:50:37spivsetmessageid: <1270795837.87.0.683673992087.issue8354@psf.upfronthosting.co.za>
2010-04-09 06:50:36spivlinkissue8354 messages
2010-04-09 06:50:34spivcreate