bpo-43356: Allow passing a signal number to interrupt_main() (GH-24755)

Also introduce a new C API ``PyErr_SetInterruptEx(int signum)``.
This commit is contained in:
Antoine Pitrou 2021-03-11 23:35:45 +01:00 committed by GitHub
parent b4fc44bb2d
commit ba251c2ae6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 211 additions and 66 deletions

View file

@ -9,6 +9,10 @@
#include <stddef.h> // offsetof()
#include "structmember.h" // PyMemberDef
#ifdef HAVE_SIGNAL_H
# include <signal.h> // SIGINT
#endif
// ThreadError is just an alias to PyExc_RuntimeError
#define ThreadError PyExc_RuntimeError
@ -1173,17 +1177,29 @@ This is synonymous to ``raise SystemExit''. It will cause the current\n\
thread to exit silently unless the exception is caught.");
static PyObject *
thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored))
thread_PyThread_interrupt_main(PyObject *self, PyObject *args)
{
PyErr_SetInterrupt();
int signum = SIGINT;
if (!PyArg_ParseTuple(args, "|i:signum", &signum)) {
return NULL;
}
if (PyErr_SetInterruptEx(signum)) {
PyErr_SetString(PyExc_ValueError, "signal number out of range");
return NULL;
}
Py_RETURN_NONE;
}
PyDoc_STRVAR(interrupt_doc,
"interrupt_main()\n\
"interrupt_main(signum=signal.SIGINT, /)\n\
\n\
Raise a KeyboardInterrupt in the main thread.\n\
A subthread can use this function to interrupt the main thread."
Simulate the arrival of the given signal in the main thread,\n\
where the corresponding signal handler will be executed.\n\
If *signum* is omitted, SIGINT is assumed.\n\
A subthread can use this function to interrupt the main thread.\n\
\n\
Note: the default signal hander for SIGINT raises ``KeyboardInterrupt``."
);
static lockobject *newlockobject(PyObject *module);
@ -1527,8 +1543,8 @@ static PyMethodDef thread_methods[] = {
METH_NOARGS, exit_doc},
{"exit", thread_PyThread_exit_thread,
METH_NOARGS, exit_doc},
{"interrupt_main", thread_PyThread_interrupt_main,
METH_NOARGS, interrupt_doc},
{"interrupt_main", (PyCFunction)thread_PyThread_interrupt_main,
METH_VARARGS, interrupt_doc},
{"get_ident", thread_get_ident,
METH_NOARGS, get_ident_doc},
#ifdef PY_HAVE_THREAD_NATIVE_ID