bpo-43963: Add _signal module state (GH-25676)

* Add signal_state_t structure and signal_global_state variable.
* Add a module state to the _signal module.
* Move and rename variables:

  * DefaultHandler becomes state->default_handler
  * IgnoreHandler becomes state->ignore_handler
  * sigint_event becomes state->sigint_event
  * ItimerError becomes modstate->itimer_error

* Rename SetHandler() to set_handler() to be consistent with
  get_handler().
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index 8618713..a4eeec9 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -4,38 +4,39 @@
 /* XXX Signals should be recorded per thread, now we have thread state. */
 
 #include "Python.h"
-#include "pycore_atomic.h"
-#include "pycore_call.h"
-#include "pycore_ceval.h"
-#include "pycore_pyerrors.h"
-#include "pycore_pylifecycle.h"
-#include "pycore_pystate.h"    // _PyThreadState_GET()
+#include "pycore_atomic.h"        // _Py_atomic_int
+#include "pycore_call.h"          // _PyObject_Call()
+#include "pycore_ceval.h"         // _PyEval_SignalReceived()
+#include "pycore_moduleobject.h"  // _PyModule_GetState()
+#include "pycore_pyerrors.h"      // _PyErr_SetString()
+#include "pycore_pylifecycle.h"   // NSIG
+#include "pycore_pystate.h"       // _PyThreadState_GET()
 
 #ifndef MS_WINDOWS
-#include "posixmodule.h"
+#  include "posixmodule.h"
 #endif
 #ifdef MS_WINDOWS
-#include "socketmodule.h"   /* needed for SOCKET_T */
+#  include "socketmodule.h"   /* needed for SOCKET_T */
 #endif
 
 #ifdef MS_WINDOWS
-#include <windows.h>
-#ifdef HAVE_PROCESS_H
-#include <process.h>
-#endif
+#  include <windows.h>
+#  ifdef HAVE_PROCESS_H
+#    include <process.h>
+#  endif
 #endif
 
 #ifdef HAVE_SIGNAL_H
-#include <signal.h>
+#  include <signal.h>
 #endif
 #ifdef HAVE_SYS_SYSCALL_H
-#include <sys/syscall.h>
+#  include <sys/syscall.h>
 #endif
 #ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
+#  include <sys/stat.h>
 #endif
 #ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
+#  include <sys/time.h>
 #endif
 
 #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
@@ -47,7 +48,7 @@
 #endif
 
 #ifndef SIG_ERR
-#define SIG_ERR ((PyOS_sighandler_t)(-1))
+#  define SIG_ERR ((PyOS_sighandler_t)(-1))
 #endif
 
 #include "clinic/signalmodule.c.h"
@@ -124,27 +125,52 @@ static volatile struct {
 /* Speed up sigcheck() when none tripped */
 static _Py_atomic_int is_tripped;
 
-static PyObject *DefaultHandler;
-static PyObject *IgnoreHandler;
-
+typedef struct {
+    PyObject *default_handler;
+    PyObject *ignore_handler;
 #ifdef MS_WINDOWS
-static HANDLE sigint_event = NULL;
+    HANDLE sigint_event;
 #endif
+} signal_state_t;
+
+// State shared by all Python interpreters
+static signal_state_t signal_global_state = {0};
 
 #if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER)
-static PyObject *ItimerError;
+#  define PYHAVE_ITIMER_ERROR
 #endif
 
+typedef struct {
+    PyObject *default_handler;  // borrowed ref (signal_global_state)
+    PyObject *ignore_handler;  // borrowed ref (signal_global_state)
+#ifdef PYHAVE_ITIMER_ERROR
+    PyObject *itimer_error;
+#endif
+} _signal_module_state;
+
+
 Py_LOCAL_INLINE(PyObject *)
-get_handler(int i) {
+get_handler(int i)
+{
     return (PyObject *)_Py_atomic_load(&Handlers[i].func);
 }
 
 Py_LOCAL_INLINE(void)
-SetHandler(int i, PyObject* func) {
+set_handler(int i, PyObject* func)
+{
     _Py_atomic_store(&Handlers[i].func, (uintptr_t)func);
 }
 
+
+static inline _signal_module_state*
+get_signal_state(PyObject *module)
+{
+    void *state = _PyModule_GetState(module);
+    assert(state != NULL);
+    return (_signal_module_state *)state;
+}
+
+
 #ifdef HAVE_GETITIMER
 /* auxiliary functions for setitimer */
 static int
@@ -359,8 +385,10 @@ signal_handler(int sig_num)
     errno = save_errno;
 
 #ifdef MS_WINDOWS
-    if (sig_num == SIGINT)
-        SetEvent(sigint_event);
+    if (sig_num == SIGINT) {
+        signal_state_t *state = &signal_global_state;
+        SetEvent(state->sigint_event);
+    }
 #endif
 }
 
@@ -459,6 +487,7 @@ static PyObject *
 signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
 /*[clinic end generated code: output=b44cfda43780f3a1 input=deee84af5fa0432c]*/
 {
+    _signal_module_state *modstate = get_signal_state(module);
     PyObject *old_handler;
     void (*func)(int);
 #ifdef MS_WINDOWS
@@ -493,10 +522,10 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
                          "signal number out of range");
         return NULL;
     }
-    if (handler == IgnoreHandler) {
+    if (handler == modstate->ignore_handler) {
         func = SIG_IGN;
     }
-    else if (handler == DefaultHandler) {
+    else if (handler == modstate->default_handler) {
         func = SIG_DFL;
     }
     else if (!PyCallable_Check(handler)) {
@@ -519,7 +548,7 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
     }
 
     old_handler = get_handler(signalnum);
-    SetHandler(signalnum, Py_NewRef(handler));
+    set_handler(signalnum, Py_NewRef(handler));
 
     if (old_handler != NULL) {
         return old_handler;
@@ -831,7 +860,6 @@ PySignal_SetWakeupFd(int fd)
 
 
 #ifdef HAVE_SETITIMER
-
 /*[clinic input]
 signal.setitimer
 
@@ -853,8 +881,9 @@ signal_setitimer_impl(PyObject *module, int which, PyObject *seconds,
                       PyObject *interval)
 /*[clinic end generated code: output=65f9dcbddc35527b input=de43daf194e6f66f]*/
 {
-    struct itimerval new;
+    _signal_module_state *modstate = get_signal_state(module);
 
+    struct itimerval new;
     if (timeval_from_double(seconds, &new.it_value) < 0) {
         return NULL;
     }
@@ -865,18 +894,16 @@ signal_setitimer_impl(PyObject *module, int which, PyObject *seconds,
     /* Let OS check "which" value */
     struct itimerval old;
     if (setitimer(which, &new, &old) != 0) {
-        PyErr_SetFromErrno(ItimerError);
+        PyErr_SetFromErrno(modstate->itimer_error);
         return NULL;
     }
 
     return itimer_retval(&old);
 }
-
-#endif
+#endif  // HAVE_SETITIMER
 
 
 #ifdef HAVE_GETITIMER
-
 /*[clinic input]
 signal.getitimer
 
@@ -890,17 +917,18 @@ static PyObject *
 signal_getitimer_impl(PyObject *module, int which)
 /*[clinic end generated code: output=9e053175d517db40 input=f7d21d38f3490627]*/
 {
-    struct itimerval old;
+    _signal_module_state *modstate = get_signal_state(module);
 
+    struct itimerval old;
     if (getitimer(which, &old) != 0) {
-        PyErr_SetFromErrno(ItimerError);
+        PyErr_SetFromErrno(modstate->itimer_error);
         return NULL;
     }
 
     return itimer_retval(&old);
 }
+#endif // HAVE_GETITIMER
 
-#endif
 
 #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGPENDING)
 static PyObject*
@@ -1544,17 +1572,17 @@ signal_add_constants(PyObject *module)
 
 
 static int
-signal_get_set_handlers(PyObject *mod_dict)
+signal_get_set_handlers(signal_state_t *state, PyObject *mod_dict)
 {
     // Get signal handlers
     for (int signum = 1; signum < NSIG; signum++) {
         void (*c_handler)(int) = PyOS_getsig(signum);
         PyObject *func;
         if (c_handler == SIG_DFL) {
-            func = DefaultHandler;
+            func = state->default_handler;
         }
         else if (c_handler == SIG_IGN) {
-            func = IgnoreHandler;
+            func = state->ignore_handler;
         }
         else {
             func = Py_None; // None of our business
@@ -1562,20 +1590,20 @@ signal_get_set_handlers(PyObject *mod_dict)
         // If signal_module_exec() is called more than one, we must
         // clear the strong reference to the previous function.
         PyObject* old_func = get_handler(signum);
-        SetHandler(signum, Py_NewRef(func));
+        set_handler(signum, Py_NewRef(func));
         Py_XDECREF(old_func);
     }
 
     // Instal Python SIGINT handler which raises KeyboardInterrupt
     PyObject* sigint_func = get_handler(SIGINT);
-    if (sigint_func == DefaultHandler) {
+    if (sigint_func == state->default_handler) {
         PyObject *int_handler = PyMapping_GetItemString(mod_dict,
                                                         "default_int_handler");
         if (!int_handler) {
             return -1;
         }
 
-        SetHandler(SIGINT, int_handler);
+        set_handler(SIGINT, int_handler);
         Py_DECREF(sigint_func);
         PyOS_setsig(SIGINT, signal_handler);
     }
@@ -1588,20 +1616,34 @@ signal_module_exec(PyObject *m)
 {
     assert(!PyErr_Occurred());
 
+    signal_state_t *state = &signal_global_state;
+    _signal_module_state *modstate = get_signal_state(m);
+
+    modstate->default_handler = state->default_handler;  // borrowed ref
+    modstate->ignore_handler = state->ignore_handler;  // borrowed ref
+
+#ifdef PYHAVE_ITIMER_ERROR
+    modstate->itimer_error = PyErr_NewException("signal.itimer_error",
+                                                PyExc_OSError, NULL);
+    if (modstate->itimer_error == NULL) {
+        return -1;
+    }
+#endif
+
     if (signal_add_constants(m) < 0) {
         return -1;
     }
 
     /* Add some symbolic constants to the module */
     PyObject *d = PyModule_GetDict(m);
-    if (PyDict_SetItemString(d, "SIG_DFL", DefaultHandler) < 0) {
+    if (PyDict_SetItemString(d, "SIG_DFL", state->default_handler) < 0) {
         return -1;
     }
-    if (PyDict_SetItemString(d, "SIG_IGN", IgnoreHandler) < 0) {
+    if (PyDict_SetItemString(d, "SIG_IGN", state->ignore_handler) < 0) {
         return -1;
     }
-#if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER)
-    if (PyDict_SetItemString(d, "ItimerError", ItimerError) < 0) {
+#ifdef PYHAVE_ITIMER_ERROR
+    if (PyDict_SetItemString(d, "ItimerError", modstate->itimer_error) < 0) {
         return -1;
     }
 #endif
@@ -1613,7 +1655,7 @@ signal_module_exec(PyObject *m)
 
     PyThreadState *tstate = _PyThreadState_GET();
     if (_Py_IsMainInterpreter(tstate->interp)) {
-        if (signal_get_set_handlers(d) < 0) {
+        if (signal_get_set_handlers(state, d) < 0) {
             return -1;
         }
     }
@@ -1623,6 +1665,31 @@ signal_module_exec(PyObject *m)
 }
 
 
+#ifdef PYHAVE_ITIMER_ERROR
+static int
+_signal_module_traverse(PyObject *module, visitproc visit, void *arg)
+{
+    _signal_module_state *modstate = get_signal_state(module);
+    Py_VISIT(modstate->itimer_error);
+    return 0;
+}
+
+static int
+_signal_module_clear(PyObject *module)
+{
+    _signal_module_state *modstate = get_signal_state(module);
+    Py_CLEAR(modstate->itimer_error);
+    return 0;
+}
+
+static void
+_signal_module_free(void *module)
+{
+    _signal_module_clear((PyObject *)module);
+}
+#endif  // PYHAVE_ITIMER_ERROR
+
+
 static PyModuleDef_Slot signal_slots[] = {
     {Py_mod_exec, signal_module_exec},
     {0, NULL}
@@ -1632,9 +1699,14 @@ static struct PyModuleDef signal_module = {
     PyModuleDef_HEAD_INIT,
     "_signal",
     .m_doc = module_doc,
-    .m_size = 0,
+    .m_size = sizeof(_signal_module_state),
     .m_methods = signal_methods,
     .m_slots = signal_slots,
+#ifdef PYHAVE_ITIMER_ERROR
+    .m_traverse = _signal_module_traverse,
+    .m_clear = _signal_module_clear,
+    .m_free = _signal_module_free,
+#endif
 };
 
 
@@ -1648,15 +1720,17 @@ PyInit__signal(void)
 void
 _PySignal_Fini(void)
 {
+    signal_state_t *state = &signal_global_state;
+
     // Restore default signals and clear handlers
     for (int signum = 1; signum < NSIG; signum++) {
         PyObject *func = get_handler(signum);
         _Py_atomic_store_relaxed(&Handlers[signum].tripped, 0);
-        SetHandler(signum, NULL);
+        set_handler(signum, NULL);
         if (func != NULL
             && func != Py_None
-            && func != DefaultHandler
-            && func != IgnoreHandler)
+            && func != state->default_handler
+            && func != state->ignore_handler)
         {
             PyOS_setsig(signum, SIG_DFL);
         }
@@ -1664,17 +1738,14 @@ _PySignal_Fini(void)
     }
 
 #ifdef MS_WINDOWS
-    if (sigint_event != NULL) {
-        CloseHandle(sigint_event);
-        sigint_event = NULL;
+    if (state->sigint_event != NULL) {
+        CloseHandle(state->sigint_event);
+        state->sigint_event = NULL;
     }
 #endif
 
-    Py_CLEAR(DefaultHandler);
-    Py_CLEAR(IgnoreHandler);
-#if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER)
-    Py_CLEAR(ItimerError);
-#endif
+    Py_CLEAR(state->default_handler);
+    Py_CLEAR(state->ignore_handler);
 }
 
 
@@ -1720,6 +1791,7 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate)
         frame = Py_None;
     }
 
+    signal_state_t *state = &signal_global_state;
     for (int i = 1; i < NSIG; i++) {
         if (!_Py_atomic_load_relaxed(&Handlers[i].tripped)) {
             continue;
@@ -1733,8 +1805,8 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate)
          * (see bpo-43406).
          */
         PyObject *func = get_handler(i);
-        if (func == NULL || func == Py_None || func == IgnoreHandler ||
-            func == DefaultHandler) {
+        if (func == NULL || func == Py_None || func == state->ignore_handler ||
+            func == state->default_handler) {
             /* No Python signal handler due to aforementioned race condition.
              * We can't call raise() as it would break the assumption
              * that PyErr_SetInterrupt() only *simulates* an incoming
@@ -1791,8 +1863,10 @@ PyErr_SetInterruptEx(int signum)
     if (signum < 1 || signum >= NSIG) {
         return -1;
     }
-    PyObject* func = get_handler(signum);
-    if (func != IgnoreHandler && func != DefaultHandler) {
+
+    signal_state_t *state = &signal_global_state;
+    PyObject *func = get_handler(signum);
+    if (func != state->ignore_handler && func != state->default_handler) {
         trip_signal(signum);
     }
     return 0;
@@ -1854,28 +1928,22 @@ _Py_RestoreSignals(void)
 int
 _PySignal_Init(int install_signal_handlers)
 {
-    DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL);
-    if (!DefaultHandler) {
+    signal_state_t *state = &signal_global_state;
+
+    state->default_handler = PyLong_FromVoidPtr((void *)SIG_DFL);
+    if (state->default_handler == NULL) {
         return -1;
     }
 
-    IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN);
-    if (!IgnoreHandler) {
+    state->ignore_handler = PyLong_FromVoidPtr((void *)SIG_IGN);
+    if (state->ignore_handler == NULL) {
         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) {
+    state->sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE);
+    if (state->sigint_event == NULL) {
         PyErr_SetFromWindowsErr(0);
         return -1;
     }
@@ -1963,13 +2031,14 @@ _PyOS_IsMainThread(void)
 }
 
 #ifdef MS_WINDOWS
+/* Returns a manual-reset event which gets tripped whenever
+   SIGINT is received.
+
+   Python.h does not include windows.h so we do cannot use HANDLE
+   as the return type of this function.  We use void* instead. */
 void *_PyOS_SigintEvent(void)
 {
-    /* Returns a manual-reset event which gets tripped whenever
-       SIGINT is received.
-
-       Python.h does not include windows.h so we do cannot use HANDLE
-       as the return type of this function.  We use void* instead. */
-    return sigint_event;
+    signal_state_t *state = &signal_global_state;
+    return state->sigint_event;
 }
 #endif