diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-04-13-16-14-16.bpo-36601.mIgS7t.rst b/Misc/NEWS.d/next/Core and Builtins/2019-04-13-16-14-16.bpo-36601.mIgS7t.rst new file mode 100644 index 00000000000..0159aae65d7 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-04-13-16-14-16.bpo-36601.mIgS7t.rst @@ -0,0 +1,2 @@ +A long-since-meaningless check for ``getpid() == main_pid`` was removed +from Python's internal C signal handler. diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 8c5a0d044ab..43a4da1a627 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -73,11 +73,12 @@ class sigset_t_converter(CConverter): /* NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS - When threads are supported, we want the following semantics: + We want the following semantics: - only the main thread can set a signal handler + - only the main thread runs the signal handler + - signals can be delivered to any thread - any thread can get a signal handler - - signals are only delivered to the main thread I.e. we don't support "synchronous signals" like SIGFPE (catching this doesn't make much sense in Python anyway) nor do we support @@ -88,17 +89,17 @@ class sigset_t_converter(CConverter): We still have the problem that in some implementations signals generated by the keyboard (e.g. SIGINT) are delivered to all threads (e.g. SGI), while in others (e.g. Solaris) such signals are - delivered to one random thread (an intermediate possibility would - be to deliver it to the main thread -- POSIX?). For now, we have - a working implementation that works in all three cases -- the - handler ignores signals if getpid() isn't the same as in the main - thread. XXX This is a hack. + delivered to one random thread. On Linux, signals are delivered to + the main thread (unless the main thread is blocking the signal, for + example because it's already handling the same signal). Since we + allow signals to be delivered to any thread, this works fine. The + only oddity is that the thread executing the Python signal handler + may not be the thread that received the signal. */ #include /* For pid_t */ #include "pythread.h" static unsigned long main_thread; -static pid_t main_pid; static PyInterpreterState *main_interp; static volatile struct { @@ -326,11 +327,7 @@ signal_handler(int sig_num) { int save_errno = errno; - /* See NOTES section above */ - if (getpid() == main_pid) - { - trip_signal(sig_num); - } + trip_signal(sig_num); #ifndef HAVE_SIGACTION #ifdef SIGCHLD @@ -1328,7 +1325,6 @@ PyInit__signal(void) int i; main_thread = PyThread_get_thread_ident(); - main_pid = getpid(); main_interp = _PyInterpreterState_Get(); /* Create the module and add the functions */ @@ -1739,7 +1735,6 @@ _PySignal_AfterFork(void) * the interpreter had an opportunity to call the handlers. issue9535. */ _clear_pending_signals(); main_thread = PyThread_get_thread_ident(); - main_pid = getpid(); main_interp = _PyInterpreterState_Get(); }