bpo-43963: Fix import _signal in subinterpreters (GH-25674)

Importing the _signal module in a subinterpreter has no longer side
effects.

signal_module_exec() no longer modifies Handlers and no longer attempts
to set SIGINT signal handler in subinterpreters.
This commit is contained in:
Victor Stinner 2021-04-28 01:50:04 +02:00 committed by GitHub
parent 6bd9288b80
commit a09766deab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 29 deletions

View file

@ -1543,6 +1543,46 @@ signal_add_constants(PyObject *module)
}
static int
signal_get_set_handlers(PyObject *mod_dict)
{
// Get signal handlers
for (int signum = 1; signum < NSIG; signum++) {
void (*c_handler)(int) = PyOS_getsig(signum);
PyObject *func;
if (c_handler == SIG_DFL) {
func = DefaultHandler;
}
else if (c_handler == SIG_IGN) {
func = IgnoreHandler;
}
else {
func = Py_None; // None of our business
}
// If signal_module_exec() is called more than one, we must
// clear the strong reference to the previous function.
PyObject* old_func = get_handler(signum);
SetHandler(signum, Py_NewRef(func));
Py_XDECREF(old_func);
}
// Instal Python SIGINT handler which raises KeyboardInterrupt
PyObject* sigint_func = get_handler(SIGINT);
if (sigint_func == DefaultHandler) {
PyObject *int_handler = PyMapping_GetItemString(mod_dict,
"default_int_handler");
if (!int_handler) {
return -1;
}
SetHandler(SIGINT, int_handler);
Py_DECREF(sigint_func);
PyOS_setsig(SIGINT, signal_handler);
}
return 0;
}
static int
signal_module_exec(PyObject *m)
{
@ -1571,37 +1611,11 @@ signal_module_exec(PyObject *m)
}
#endif
// Get signal handlers
for (int signum = 1; signum < NSIG; signum++) {
void (*c_handler)(int) = PyOS_getsig(signum);
PyObject *func;
if (c_handler == SIG_DFL) {
func = DefaultHandler;
}
else if (c_handler == SIG_IGN) {
func = IgnoreHandler;
}
else {
func = Py_None; // None of our business
}
// If signal_module_exec() is called more than one, we must
// clear the strong reference to the previous function.
PyObject* old_func = get_handler(signum);
SetHandler(signum, Py_NewRef(func));
Py_XDECREF(old_func);
}
// Instal Python SIGINT handler which raises KeyboardInterrupt
PyObject* sigint_func = get_handler(SIGINT);
if (sigint_func == DefaultHandler) {
PyObject *int_handler = PyMapping_GetItemString(d, "default_int_handler");
if (!int_handler) {
PyThreadState *tstate = _PyThreadState_GET();
if (_Py_IsMainInterpreter(tstate->interp)) {
if (signal_get_set_handlers(d) < 0) {
return -1;
}
SetHandler(SIGINT, int_handler);
Py_DECREF(sigint_func);
PyOS_setsig(SIGINT, signal_handler);
}
assert(!PyErr_Occurred());