Author njs
Recipients bkabrda, neologix, njs, pitrou, vstinner
Date 2017-03-23.04:57:12
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
Letting Python-level signal handlers run in arbitrary threads is an interesting idea, but it's a non-trivial change to Python semantics that may well break some programs (previously it was guaranteed that signal handlers couldn't race with main thread code), and it doesn't fully fix the bug here (because it's common for Python programs to contain threads which don't run Python code, e.g. if they use zmq). I can imagine some potential benefits, but I feel like this needs some substantial rationale?

OTOH the pthread_kill-based fix I suggested is like 3 lines and AFAICT fixes the problem exactly.

> I dislike the idea of transfering the signal to the main thread from another thread in the C signal handler using pthread_kill(). Most code behave very badly when getting a signal, so getting a signal twice is likely to double the pain.

This doesn't make much sense to me... CPython's pretty good at handling EINTR these days, and, well, the only case that's different is when you have a signal handler that needs to be run and the main thread is blocked in a syscall, which is exactly the case that's currently broken? 

> Moreover, pthread_sigmask() can block signals in the main thread for deliberate reasons.

Sure, and with pthread_kill() this would have the effect that the signal would be queued by the kernel and delivered after signal is unmasked. That seems like pretty sensible semantics to me; in fact it's exactly what you get in single-threaded code.

Compare that to right now where AFAICT pthread_sigmask() is pretty useless in the presence of threads, because of the thing where if one thread has a signal blocked then the kernel will pick another thread to deliver it to.

> From the point of view of the Python signal handler, the current "if (PyThread_get_thread_ident() != main_thread) return 0;" code in the C signal handler is somehow an implicit pthread_sigmask(signal.SIG_BLOCK, range(1, signal.NSIG)) on all threads except of the main thread, whereas Unix gives a fine control on these masks with the pthread_sigmask() function.

That code isn't in the C signal handler, it's in the code that the interpreter runs occasionally to check if the C signal handler has been called, right?
Date User Action Args
2017-03-23 04:57:13njssetrecipients: + njs, pitrou, vstinner, neologix, bkabrda
2017-03-23 04:57:13njssetmessageid: <>
2017-03-23 04:57:13njslinkissue21895 messages
2017-03-23 04:57:12njscreate