mirror of
https://github.com/python/cpython.git
synced 2025-08-03 00:23:06 +00:00
bpo-35724: Explicitly require the main interpreter for signal-handling. (GH-11530)
Ensure that the main interpreter is active (in the main thread) for signal-handling operations. This is increasingly relevant as people use subinterpreters more. https://bugs.python.org/issue35724
This commit is contained in:
parent
06babb2422
commit
64d6cc826d
4 changed files with 39 additions and 9 deletions
|
@ -99,6 +99,7 @@ class sigset_t_converter(CConverter):
|
|||
#include "pythread.h"
|
||||
static unsigned long main_thread;
|
||||
static pid_t main_pid;
|
||||
static PyInterpreterState *main_interp;
|
||||
|
||||
static volatile struct {
|
||||
_Py_atomic_int tripped;
|
||||
|
@ -185,6 +186,13 @@ itimer_retval(struct itimerval *iv)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
is_main(void)
|
||||
{
|
||||
return PyThread_get_thread_ident() == main_thread &&
|
||||
_PyInterpreterState_Get() == main_interp;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
signal_default_int_handler(PyObject *self, PyObject *args)
|
||||
{
|
||||
|
@ -464,7 +472,7 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
|
|||
return NULL;
|
||||
}
|
||||
#endif
|
||||
if (PyThread_get_thread_ident() != main_thread) {
|
||||
if (!is_main()) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"signal only works in main thread");
|
||||
return NULL;
|
||||
|
@ -486,7 +494,7 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
|
|||
else
|
||||
func = signal_handler;
|
||||
/* Check for pending signals before changing signal handler */
|
||||
if (PyErr_CheckSignals()) {
|
||||
if (_PyErr_CheckSignals()) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyOS_setsig(signalnum, func) == SIG_ERR) {
|
||||
|
@ -681,7 +689,7 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds)
|
|||
return NULL;
|
||||
#endif
|
||||
|
||||
if (PyThread_get_thread_ident() != main_thread) {
|
||||
if (!is_main()) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"set_wakeup_fd only works in main thread");
|
||||
return NULL;
|
||||
|
@ -1314,6 +1322,7 @@ PyInit__signal(void)
|
|||
|
||||
main_thread = PyThread_get_thread_ident();
|
||||
main_pid = getpid();
|
||||
main_interp = _PyInterpreterState_Get();
|
||||
|
||||
/* Create the module and add the functions */
|
||||
m = PyModule_Create(&signalmodule);
|
||||
|
@ -1606,6 +1615,18 @@ finisignal(void)
|
|||
/* Declared in pyerrors.h */
|
||||
int
|
||||
PyErr_CheckSignals(void)
|
||||
{
|
||||
if (!is_main()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _PyErr_CheckSignals();
|
||||
}
|
||||
|
||||
|
||||
/* Declared in cpython/pyerrors.h */
|
||||
int
|
||||
_PyErr_CheckSignals(void)
|
||||
{
|
||||
int i;
|
||||
PyObject *f;
|
||||
|
@ -1613,9 +1634,6 @@ PyErr_CheckSignals(void)
|
|||
if (!_Py_atomic_load(&is_tripped))
|
||||
return 0;
|
||||
|
||||
if (PyThread_get_thread_ident() != main_thread)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The is_tripped variable is meant to speed up the calls to
|
||||
* PyErr_CheckSignals (both directly or via pending calls) when no
|
||||
|
@ -1687,8 +1705,9 @@ int
|
|||
PyOS_InterruptOccurred(void)
|
||||
{
|
||||
if (_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) {
|
||||
if (PyThread_get_thread_ident() != main_thread)
|
||||
if (!is_main()) {
|
||||
return 0;
|
||||
}
|
||||
_Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1716,12 +1735,13 @@ _PySignal_AfterFork(void)
|
|||
_clear_pending_signals();
|
||||
main_thread = PyThread_get_thread_ident();
|
||||
main_pid = getpid();
|
||||
main_interp = _PyInterpreterState_Get();
|
||||
}
|
||||
|
||||
int
|
||||
_PyOS_IsMainThread(void)
|
||||
{
|
||||
return PyThread_get_thread_ident() == main_thread;
|
||||
return is_main();
|
||||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue