From e9810a7edf245be9985d3f187bfc7ccb6494c55d Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 11 Jan 2019 14:13:12 -0700 Subject: [PATCH 1/5] Factor out _PyErr_CheckSignals(). --- Include/cpython/pyerrors.h | 1 + Modules/signalmodule.c | 17 +++++++++++++---- Python/ceval.c | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Include/cpython/pyerrors.h b/Include/cpython/pyerrors.h index 0b43d7528b97598..de6548dc9c0bb57 100644 --- a/Include/cpython/pyerrors.h +++ b/Include/cpython/pyerrors.h @@ -133,6 +133,7 @@ PyAPI_FUNC(PyObject *) _PyErr_TrySetFromCause( /* In signalmodule.c */ int PySignal_SetWakeupFd(int fd); +PyAPI_FUNC(int) _PyErr_CheckSignals(void); /* Support for adding program text to SyntaxErrors */ diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 9d49cbd14400972..d65e4a047512f22 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -486,7 +486,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) { @@ -1606,6 +1606,18 @@ finisignal(void) /* Declared in pyerrors.h */ int PyErr_CheckSignals(void) +{ + if (PyThread_get_thread_ident() != main_thread) { + return 0; + } + + return _PyErr_CheckSignals(); +} + + +/* Declared in cpython/pyerrors.h */ +int +_PyErr_CheckSignals(void) { int i; PyObject *f; @@ -1613,9 +1625,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 diff --git a/Python/ceval.c b/Python/ceval.c index 03456f6d2ab4f6f..5e242d2d6100f11 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -381,7 +381,7 @@ handle_signals(void) } UNSIGNAL_PENDING_SIGNALS(); - if (PyErr_CheckSignals() < 0) { + if (_PyErr_CheckSignals() < 0) { SIGNAL_PENDING_SIGNALS(); /* We're not done yet */ return -1; } From a1c89acede658a0f8fc12864129149ed822bf687 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 11 Jan 2019 14:39:19 -0700 Subject: [PATCH 2/5] Factor out is_main(). --- Modules/signalmodule.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index d65e4a047512f22..90dd384074686a0 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -185,6 +185,12 @@ itimer_retval(struct itimerval *iv) } #endif +int +is_main(void) +{ + return PyThread_get_thread_ident() == main_thread; +} + static PyObject * signal_default_int_handler(PyObject *self, PyObject *args) { @@ -464,7 +470,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; @@ -681,7 +687,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; @@ -1607,7 +1613,7 @@ finisignal(void) int PyErr_CheckSignals(void) { - if (PyThread_get_thread_ident() != main_thread) { + if (!is_main()) { return 0; } @@ -1696,8 +1702,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; } @@ -1730,7 +1737,7 @@ _PySignal_AfterFork(void) int _PyOS_IsMainThread(void) { - return PyThread_get_thread_ident() == main_thread; + return is_main(); } #ifdef MS_WINDOWS From c21d282f75850d3b61e18b340e5b54c3b4a42192 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 11 Jan 2019 14:41:17 -0700 Subject: [PATCH 3/5] Also check if is main interpreter. --- Modules/signalmodule.c | 6 +++++- Python/ceval.c | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 90dd384074686a0..86dc3d57579d85b 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; @@ -188,7 +189,8 @@ itimer_retval(struct itimerval *iv) int is_main(void) { - return PyThread_get_thread_ident() == main_thread; + return PyThread_get_thread_ident() == main_thread && + _PyInterpreterState_Get() == main_interp; } static PyObject * @@ -1320,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); @@ -1732,6 +1735,7 @@ _PySignal_AfterFork(void) _clear_pending_signals(); main_thread = PyThread_get_thread_ident(); main_pid = getpid(); + main_interp = _PyInterpreterState_Get(); } int diff --git a/Python/ceval.c b/Python/ceval.c index 5e242d2d6100f11..439f4f156e8b09c 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -379,6 +379,13 @@ handle_signals(void) { return 0; } + /* + * Ensure that the thread isn't currently running some other + * interpreter. + */ + if (_PyInterpreterState_GET_UNSAFE() != _PyRuntime.interpreters.main) { + return 0; + } UNSIGNAL_PENDING_SIGNALS(); if (_PyErr_CheckSignals() < 0) { From f18e34d442e16780099174d99502a7626cfa1ed2 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Fri, 11 Jan 2019 14:46:19 -0700 Subject: [PATCH 4/5] Add a NEWS entry. --- .../Core and Builtins/2019-01-11-14-46-08.bpo-35724.Wv79MG.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-01-11-14-46-08.bpo-35724.Wv79MG.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-01-11-14-46-08.bpo-35724.Wv79MG.rst b/Misc/NEWS.d/next/Core and Builtins/2019-01-11-14-46-08.bpo-35724.Wv79MG.rst new file mode 100644 index 000000000000000..d2d74e56cb2187b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-01-11-14-46-08.bpo-35724.Wv79MG.rst @@ -0,0 +1,2 @@ +Signal-handling is now guaranteed to happen relative to the main +interpreter. From c5742f2dbe2cb2d156e6b7a3ec7154eb737d14ab Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Sat, 23 Feb 2019 11:21:55 -0800 Subject: [PATCH 5/5] Make a function static. --- Modules/signalmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 86dc3d57579d85b..f29720bcaf3637e 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -186,7 +186,7 @@ itimer_retval(struct itimerval *iv) } #endif -int +static int is_main(void) { return PyThread_get_thread_ident() == main_thread &&