summaryrefslogtreecommitdiffstats
path: root/Modules/signalmodule.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-11-17 17:15:20 (GMT)
committerGitHub <noreply@github.com>2020-11-17 17:15:20 (GMT)
commit0ae323b87f1bed64a7fa70f5a41a5800aca032cc (patch)
tree2aa675a3ee9e6f29d1440a84eb15559074da2460 /Modules/signalmodule.c
parenta1f401a58b213e400fbd8f0fa8dc5260a2389dab (diff)
downloadcpython-0ae323b87f1bed64a7fa70f5a41a5800aca032cc.zip
cpython-0ae323b87f1bed64a7fa70f5a41a5800aca032cc.tar.gz
cpython-0ae323b87f1bed64a7fa70f5a41a5800aca032cc.tar.bz2
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.
Diffstat (limited to 'Modules/signalmodule.c')
-rw-r--r--Modules/signalmodule.c140
1 files changed, 87 insertions, 53 deletions
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index c0b2117..7cd6666 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -130,15 +130,16 @@ static _Py_atomic_int is_tripped;
static PyObject *DefaultHandler;
static PyObject *IgnoreHandler;
-static PyObject *IntHandler;
#ifdef MS_WINDOWS
static HANDLE sigint_event = NULL;
#endif
-#ifdef HAVE_GETITIMER
+#if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER)
static PyObject *ItimerError;
+#endif
+#ifdef HAVE_GETITIMER
/* auxiliary functions for setitimer */
static int
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)
-static int initialized;
static PyStructSequence_Field struct_siginfo_fields[] = {
{"si_signo", "signal number"},
{"si_code", "signal code"},
@@ -1384,30 +1384,19 @@ signal_exec(PyObject *m)
{
/* add the functions */
#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) {
return -1;
}
- initialized = 1;
#endif
/* Add some symbolic constants to the module */
PyObject *d = PyModule_GetDict(m);
- DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
- if (!DefaultHandler ||
- PyDict_SetItemString(d, "SIG_DFL", DefaultHandler) < 0) {
+ if (PyDict_SetItemString(d, "SIG_DFL", DefaultHandler) < 0) {
return -1;
}
- IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
- if (!IgnoreHandler ||
- PyDict_SetItemString(d, "SIG_IGN", IgnoreHandler) < 0) {
+ if (PyDict_SetItemString(d, "SIG_IGN", IgnoreHandler) < 0) {
return -1;
}
@@ -1427,15 +1416,9 @@ signal_exec(PyObject *m)
return -1;
#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++) {
void (*t)(int);
t = PyOS_getsig(i);
- _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
if (t == SIG_DFL)
Handlers[i].func = DefaultHandler;
else if (t == SIG_IGN)
@@ -1445,9 +1428,13 @@ signal_exec(PyObject *m)
Py_INCREF(Handlers[i].func);
}
if (Handlers[SIGINT].func == DefaultHandler) {
+ PyObject *int_handler = PyMapping_GetItemString(d, "default_int_handler");
+ if (!int_handler) {
+ return -1;
+ }
+
/* Install default int handler */
- Py_INCREF(IntHandler);
- Py_SETREF(Handlers[SIGINT].func, IntHandler);
+ Py_SETREF(Handlers[SIGINT].func, int_handler);
PyOS_setsig(SIGINT, signal_handler);
}
@@ -1617,11 +1604,8 @@ signal_exec(PyObject *m)
return -1;
#endif
-#if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER)
- ItimerError = PyErr_NewException("signal.ItimerError",
- PyExc_OSError, NULL);
- if (!ItimerError ||
- PyDict_SetItemString(d, "ItimerError", ItimerError) < 0) {
+#if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER)
+ if (PyDict_SetItemString(d, "ItimerError", ItimerError) < 0) {
return -1;
}
#endif
@@ -1636,11 +1620,6 @@ signal_exec(PyObject *m)
return -1;
#endif
-#ifdef MS_WINDOWS
- /* Create manual-reset event, initially unset */
- sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE);
-#endif
-
if (PyErr_Occurred()) {
return -1;
}
@@ -1677,23 +1656,31 @@ PyInit__signal(void)
void
_PySignal_Fini(void)
{
- int i;
- PyObject *func;
-
- for (i = 1; i < NSIG; i++) {
- func = Handlers[i].func;
- _Py_atomic_store_relaxed(&Handlers[i].tripped, 0);
- Handlers[i].func = NULL;
- if (func != NULL && func != Py_None &&
- func != DefaultHandler && func != IgnoreHandler)
- PyOS_setsig(i, SIG_DFL);
+ // Restore default signals and clear handlers
+ for (int signum = 1; signum < NSIG; signum++) {
+ PyObject *func = Handlers[signum].func;
+ _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0);
+ Handlers[signum].func = NULL;
+ if (func != NULL
+ && func != Py_None
+ && func != DefaultHandler
+ && func != IgnoreHandler)
+ {
+ PyOS_setsig(signum, SIG_DFL);
+ }
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(IgnoreHandler);
-#ifdef HAVE_GETITIMER
+#if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER)
Py_CLEAR(ItimerError);
#endif
}
@@ -1792,14 +1779,9 @@ PyErr_SetInterrupt(void)
}
}
-int
-_PySignal_Init(int install_signal_handlers)
+static int
+signal_install_handlers(void)
{
- if (!install_signal_handlers) {
- // Nothing to do
- return 0;
- }
-
#ifdef SIGPIPE
PyOS_setsig(SIGPIPE, SIG_IGN);
#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
int
_PyOS_InterruptOccurred(PyThreadState *tstate)