Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
A long-since-meaningless check for ``getpid() == main_pid`` was removed
from Python's internal C signal handler.
25 changes: 10 additions & 15 deletions Modules/signalmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 <sys/types.h> /* For pid_t */
#include "pythread.h"
static unsigned long main_thread;
static pid_t main_pid;
static PyInterpreterState *main_interp;

static volatile struct {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -1741,7 +1737,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();
}

Expand Down