Nathaniel Smith added the comment:

It turns out that this bug is more general than signal.pause, and has caused 
problems for a few different people:
  https://github.com/dabeaz/curio/issues/118#issuecomment-287735781
  https://github.com/dabeaz/curio/issues/118#issuecomment-287798241
  https://github.com/dabeaz/curio/issues/118#issuecomment-287887843

The basic problem is that CPython's signal handling strategy on Unix-likes 
assumes that if a signal is delivered to the process at a time when the main 
thread is blocked in a syscall, then that syscall will promptly exit with 
EINTR. So for example, time.sleep has some clever code on Windows to make it 
interruptible with control-C, but on Unix we assume that the kernel will break 
the sleep for us.

The problem with this is that POSIX only guarantees that *some* thread will 
receive the signal -- not necessarily the main thread. In practice it seems 
like most implementations do deliver most signals to the main thread or CPython 
wouldn't have gotten away with this for as long as it has, but in particular it 
seems like Linux is happy to deliver SIGCHLD to random other threads. So the 
C-level signal handler runs in whatever thread, it sets the flag for the main 
thread to run the Python-level signal handler... and then the main thread sits 
there blocked in sleep() or select() or pause() or whatever, and never checks 
the flag.

A simple solution would be to make sure signals are always delivered to the 
main thread, by adjusting the C-level signal handler to do something like:

if (current_thread != main_thread) {
    pthread_kill(main_thread, sig_num);
    return;
}

----------
nosy: +njs
title: signal.pause() doesn't wake up on SIGCHLD in non-main thread -> 
signal.pause() and signal handlers don't react to SIGCHLD in non-main thread
versions: +Python 3.6, Python 3.7

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue21895>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to