diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2019-02-23 22:40:43 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-23 22:40:43 (GMT) |
commit | 64d6cc826dacebc2493b1bb5e8cb97828eb76f81 (patch) | |
tree | 93185a0a288ead9ac51ccaa606cd2aae7a4e45ed /Modules | |
parent | 06babb24225d41a76e4aee975380294ca1ee1d7c (diff) | |
download | cpython-64d6cc826dacebc2493b1bb5e8cb97828eb76f81.zip cpython-64d6cc826dacebc2493b1bb5e8cb97828eb76f81.tar.gz cpython-64d6cc826dacebc2493b1bb5e8cb97828eb76f81.tar.bz2 |
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
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/signalmodule.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 9d49cbd..f29720b 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -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); @@ -1607,15 +1616,24 @@ finisignal(void) 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; 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 |