mirror of
https://github.com/python/cpython.git
synced 2025-10-12 01:43:12 +00:00
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:
parent
6bd9288b80
commit
a09766deab
2 changed files with 45 additions and 29 deletions
|
@ -0,0 +1,2 @@
|
||||||
|
Importing the :mod:`_signal` module in a subinterpreter has no longer side
|
||||||
|
effects.
|
|
@ -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
|
static int
|
||||||
signal_module_exec(PyObject *m)
|
signal_module_exec(PyObject *m)
|
||||||
{
|
{
|
||||||
|
@ -1571,37 +1611,11 @@ signal_module_exec(PyObject *m)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get signal handlers
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
for (int signum = 1; signum < NSIG; signum++) {
|
if (_Py_IsMainInterpreter(tstate->interp)) {
|
||||||
void (*c_handler)(int) = PyOS_getsig(signum);
|
if (signal_get_set_handlers(d) < 0) {
|
||||||
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) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetHandler(SIGINT, int_handler);
|
|
||||||
Py_DECREF(sigint_func);
|
|
||||||
PyOS_setsig(SIGINT, signal_handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!PyErr_Occurred());
|
assert(!PyErr_Occurred());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue