mirror of
https://github.com/python/cpython.git
synced 2025-07-25 12:14:38 +00:00
bpo-41686: Always create the SIGINT event on Windows (GH-23344)
bpo-41686, bpo-41713: On Windows, the SIGINT event, _PyOS_SigintEvent(), is now created even if Python is configured to not install signal handlers (PyConfig.install_signal_handlers=0 or Py_InitializeEx(0)). Changes: * Move global variables initialization from signal_exec() to _PySignal_Init() to clarify that they are global variables cleared by _PySignal_Fini(). * _PySignal_Fini() now closes sigint_event. * IntHandler is no longer a global variable.
This commit is contained in:
parent
a1f401a58b
commit
0ae323b87f
2 changed files with 91 additions and 53 deletions
|
@ -0,0 +1,4 @@
|
||||||
|
On Windows, the ``SIGINT`` event, ``_PyOS_SigintEvent()``, is now created
|
||||||
|
even if Python is configured to not install signal handlers (if
|
||||||
|
:c:member:`PyConfig.install_signal_handlers` equals to 0, or
|
||||||
|
``Py_InitializeEx(0)``).
|
|
@ -130,15 +130,16 @@ static _Py_atomic_int is_tripped;
|
||||||
|
|
||||||
static PyObject *DefaultHandler;
|
static PyObject *DefaultHandler;
|
||||||
static PyObject *IgnoreHandler;
|
static PyObject *IgnoreHandler;
|
||||||
static PyObject *IntHandler;
|
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
static HANDLE sigint_event = NULL;
|
static HANDLE sigint_event = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_GETITIMER
|
#if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER)
|
||||||
static PyObject *ItimerError;
|
static PyObject *ItimerError;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_GETITIMER
|
||||||
/* auxiliary functions for setitimer */
|
/* auxiliary functions for setitimer */
|
||||||
static int
|
static int
|
||||||
timeval_from_double(PyObject *obj, struct timeval *tv)
|
timeval_from_double(PyObject *obj, struct timeval *tv)
|
||||||
|
@ -1074,7 +1075,6 @@ signal_valid_signals_impl(PyObject *module)
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
|
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
|
||||||
static int initialized;
|
|
||||||
static PyStructSequence_Field struct_siginfo_fields[] = {
|
static PyStructSequence_Field struct_siginfo_fields[] = {
|
||||||
{"si_signo", "signal number"},
|
{"si_signo", "signal number"},
|
||||||
{"si_code", "signal code"},
|
{"si_code", "signal code"},
|
||||||
|
@ -1384,30 +1384,19 @@ signal_exec(PyObject *m)
|
||||||
{
|
{
|
||||||
/* add the functions */
|
/* add the functions */
|
||||||
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
|
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
|
||||||
if (!initialized) {
|
|
||||||
if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PyModule_AddType(m, &SiginfoType) < 0) {
|
if (PyModule_AddType(m, &SiginfoType) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
initialized = 1;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Add some symbolic constants to the module */
|
/* Add some symbolic constants to the module */
|
||||||
PyObject *d = PyModule_GetDict(m);
|
PyObject *d = PyModule_GetDict(m);
|
||||||
|
|
||||||
DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
|
if (PyDict_SetItemString(d, "SIG_DFL", DefaultHandler) < 0) {
|
||||||
if (!DefaultHandler ||
|
|
||||||
PyDict_SetItemString(d, "SIG_DFL", DefaultHandler) < 0) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
|
if (PyDict_SetItemString(d, "SIG_IGN", IgnoreHandler) < 0) {
|
||||||
if (!IgnoreHandler ||
|
|
||||||
PyDict_SetItemString(d, "SIG_IGN", IgnoreHandler) < 0) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1427,15 +1416,9 @@ signal_exec(PyObject *m)
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IntHandler = PyMapping_GetItemString(d, "default_int_handler");
|
|
||||||
if (!IntHandler)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
_Py_atomic_store_relaxed(&Handlers[0].tripped, 0);
|
|
||||||
for (int i = 1; i < NSIG; i++) {
|
for (int i = 1; i < NSIG; i++) {
|
||||||
void (*t)(int);
|
void (*t)(int);
|
||||||
t = PyOS_getsig(i);
|
t = PyOS_getsig(i);
|
||||||
_Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
|
|
||||||
if (t == SIG_DFL)
|
if (t == SIG_DFL)
|
||||||
Handlers[i].func = DefaultHandler;
|
Handlers[i].func = DefaultHandler;
|
||||||
else if (t == SIG_IGN)
|
else if (t == SIG_IGN)
|
||||||
|
@ -1445,9 +1428,13 @@ signal_exec(PyObject *m)
|
||||||
Py_INCREF(Handlers[i].func);
|
Py_INCREF(Handlers[i].func);
|
||||||
}
|
}
|
||||||
if (Handlers[SIGINT].func == DefaultHandler) {
|
if (Handlers[SIGINT].func == DefaultHandler) {
|
||||||
|
PyObject *int_handler = PyMapping_GetItemString(d, "default_int_handler");
|
||||||
|
if (!int_handler) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Install default int handler */
|
/* Install default int handler */
|
||||||
Py_INCREF(IntHandler);
|
Py_SETREF(Handlers[SIGINT].func, int_handler);
|
||||||
Py_SETREF(Handlers[SIGINT].func, IntHandler);
|
|
||||||
PyOS_setsig(SIGINT, signal_handler);
|
PyOS_setsig(SIGINT, signal_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1617,11 +1604,8 @@ signal_exec(PyObject *m)
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER)
|
#if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER)
|
||||||
ItimerError = PyErr_NewException("signal.ItimerError",
|
if (PyDict_SetItemString(d, "ItimerError", ItimerError) < 0) {
|
||||||
PyExc_OSError, NULL);
|
|
||||||
if (!ItimerError ||
|
|
||||||
PyDict_SetItemString(d, "ItimerError", ItimerError) < 0) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1636,11 +1620,6 @@ signal_exec(PyObject *m)
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
/* Create manual-reset event, initially unset */
|
|
||||||
sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1677,23 +1656,31 @@ PyInit__signal(void)
|
||||||
void
|
void
|
||||||
_PySignal_Fini(void)
|
_PySignal_Fini(void)
|
||||||
{
|
{
|
||||||
int i;
|
// Restore default signals and clear handlers
|
||||||
PyObject *func;
|
for (int signum = 1; signum < NSIG; signum++) {
|
||||||
|
PyObject *func = Handlers[signum].func;
|
||||||
for (i = 1; i < NSIG; i++) {
|
_Py_atomic_store_relaxed(&Handlers[signum].tripped, 0);
|
||||||
func = Handlers[i].func;
|
Handlers[signum].func = NULL;
|
||||||
_Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
|
if (func != NULL
|
||||||
Handlers[i].func = NULL;
|
&& func != Py_None
|
||||||
if (func != NULL && func != Py_None &&
|
&& func != DefaultHandler
|
||||||
func != DefaultHandler && func != IgnoreHandler)
|
&& func != IgnoreHandler)
|
||||||
PyOS_setsig(i, SIG_DFL);
|
{
|
||||||
|
PyOS_setsig(signum, SIG_DFL);
|
||||||
|
}
|
||||||
Py_XDECREF(func);
|
Py_XDECREF(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_CLEAR(IntHandler);
|
#ifdef MS_WINDOWS
|
||||||
|
if (sigint_event != NULL) {
|
||||||
|
CloseHandle(sigint_event);
|
||||||
|
sigint_event = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Py_CLEAR(DefaultHandler);
|
Py_CLEAR(DefaultHandler);
|
||||||
Py_CLEAR(IgnoreHandler);
|
Py_CLEAR(IgnoreHandler);
|
||||||
#ifdef HAVE_GETITIMER
|
#if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER)
|
||||||
Py_CLEAR(ItimerError);
|
Py_CLEAR(ItimerError);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1792,14 +1779,9 @@ PyErr_SetInterrupt(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
_PySignal_Init(int install_signal_handlers)
|
signal_install_handlers(void)
|
||||||
{
|
{
|
||||||
if (!install_signal_handlers) {
|
|
||||||
// Nothing to do
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SIGPIPE
|
#ifdef SIGPIPE
|
||||||
PyOS_setsig(SIGPIPE, SIG_IGN);
|
PyOS_setsig(SIGPIPE, SIG_IGN);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1821,6 +1803,58 @@ _PySignal_Init(int install_signal_handlers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
_PySignal_Init(int install_signal_handlers)
|
||||||
|
{
|
||||||
|
DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
|
||||||
|
if (!DefaultHandler) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
|
||||||
|
if (!IgnoreHandler) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER)
|
||||||
|
ItimerError = PyErr_NewException("signal.ItimerError",
|
||||||
|
PyExc_OSError, NULL);
|
||||||
|
if (!ItimerError) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
/* Create manual-reset event, initially unset */
|
||||||
|
sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE);
|
||||||
|
if (sigint_event == NULL) {
|
||||||
|
PyErr_SetFromWindowsErr(0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT)
|
||||||
|
if (SiginfoType.tp_name == NULL) {
|
||||||
|
if (PyStructSequence_InitType2(&SiginfoType, &struct_siginfo_desc) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int signum = 1; signum < NSIG; signum++) {
|
||||||
|
_Py_atomic_store_relaxed(&Handlers[signum].tripped, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (install_signal_handlers) {
|
||||||
|
if (signal_install_handlers() < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// The caller doesn't have to hold the GIL
|
// The caller doesn't have to hold the GIL
|
||||||
int
|
int
|
||||||
_PyOS_InterruptOccurred(PyThreadState *tstate)
|
_PyOS_InterruptOccurred(PyThreadState *tstate)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue