diff -r df326e723384 Modules/signalmodule.c --- a/Modules/signalmodule.c Thu Aug 16 23:10:28 2012 +0200 +++ b/Modules/signalmodule.c Thu Aug 16 23:18:09 2012 +0200 @@ -93,14 +93,69 @@ PyObject *func; } Handlers[NSIG]; -static volatile sig_atomic_t wakeup_fd = -1; /* Speed up sigcheck() when none tripped */ + static volatile sig_atomic_t is_tripped = 0; +static volatile sig_atomic_t wakeup_fd; -static PyObject *DefaultHandler; -static PyObject *IgnoreHandler; -static PyObject *IntHandler; +typedef struct { + int initialized; + PyObject *DefaultHandler; + PyObject *IgnoreHandler; + PyObject *IntHandler; +#if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) + PyObject *ItimerError; +#endif +#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) + PyObject *SiginfoType; +#endif +} signalstate; + + +#define signal_state(o) ((signalstate *)PyModule_GetState(o)) + +static int +signal_clear(PyObject *m) +{ + signalstate *state = signal_state(m); + Py_CLEAR(state->DefaultHandler); + Py_CLEAR(state->IgnoreHandler); + Py_CLEAR(state->IntHandler); +#if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) + Py_CLEAR(state->ItimerError); +#endif +#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) + Py_CLEAR(state->SiginfoType); +#endif + return 0; +} + +static int +signal_traverse(PyObject *m, visitproc visit, void *arg) +{ + signalstate *state = signal_state(m); + Py_VISIT(state->DefaultHandler); + Py_VISIT(state->IgnoreHandler); + Py_VISIT(state->IntHandler); +#if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) + Py_VISIT(state->ItimerError); +#endif +#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) + Py_VISIT(state->SiginfoType); +#endif + return 0; +} + +static void +signal_free(void *m) +{ + signal_clear((PyObject *)m); +} + +static PyModuleDef signalmodule; + +#define signalstate_global ((signalstate *)PyModule_GetState(PyState_FindModule(&signalmodule))) /* On Solaris 8, gcc will produce a warning that the function declaration is not a prototype. This is caused by the definition of @@ -114,7 +169,7 @@ #endif #ifdef HAVE_GETITIMER -static PyObject *ItimerError; + /* auxiliary functions for setitimer/getitimer */ static void @@ -322,9 +377,9 @@ "signal number out of range"); return NULL; } - if (obj == IgnoreHandler) + if (obj == signalstate_global->IgnoreHandler) func = SIG_IGN; - else if (obj == DefaultHandler) + else if (obj == signalstate_global->DefaultHandler) func = SIG_DFL; else if (!PyCallable_Check(obj)) { PyErr_SetString(PyExc_TypeError, @@ -473,7 +528,7 @@ timeval_from_double(interval, &new.it_interval); /* Let OS check "which" value */ if (setitimer(which, &new, &old) != 0) { - PyErr_SetFromErrno(ItimerError); + PyErr_SetFromErrno(signalstate_global->ItimerError); return NULL; } @@ -503,7 +558,7 @@ return NULL; if (getitimer(which, &old) != 0) { - PyErr_SetFromErrno(ItimerError); + PyErr_SetFromErrno(signalstate_global->ItimerError); return NULL; } @@ -690,7 +745,7 @@ #endif /* #ifdef HAVE_SIGPENDING */ #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) -static int initialized; + static PyStructSequence_Field struct_siginfo_fields[] = { {"si_signo", "signal number"}, {"si_code", "signal code"}, @@ -715,12 +770,13 @@ 7 /* n_in_sequence */ }; -static PyTypeObject SiginfoType; + static PyObject * fill_siginfo(siginfo_t *si) { - PyObject *result = PyStructSequence_New(&SiginfoType); + PyObject *result = PyStructSequence_New( + (PyTypeObject *)signalstate_global->SiginfoType); if (!result) return NULL; @@ -736,7 +792,7 @@ Py_DECREF(result); return NULL; } - + Py_INCREF(signalstate_global->SiginfoType); return result; } #endif @@ -943,12 +999,12 @@ PyModuleDef_HEAD_INIT, "signal", module_doc, - -1, + sizeof(signalstate), signal_methods, NULL, - NULL, - NULL, - NULL + signal_traverse, + signal_clear, + signal_free }; PyMODINIT_FUNC @@ -956,34 +1012,46 @@ { PyObject *m, *d, *x; int i; + signalstate *state; #ifdef WITH_THREAD main_thread = PyThread_get_thread_ident(); main_pid = getpid(); #endif - /* Create the module and add the functions */ - m = PyModule_Create(&signalmodule); - if (m == NULL) - return NULL; + m = PyState_FindModule(&signalmodule); + if(m == NULL) { + /* Create the module and add the functions */ + m = PyModule_Create(&signalmodule); + if (m == NULL) + return NULL; + signal_state(m)->initialized = 0; + } + + state = signal_state(m); + + PyState_AddModule(m, &signalmodule); + wakeup_fd = -1; #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) - if (!initialized) - PyStructSequence_InitType(&SiginfoType, &struct_siginfo_desc); + if (!state->initialized) { + state->SiginfoType = + (PyObject *)PyStructSequence_NewType(&struct_siginfo_desc); + } - Py_INCREF((PyObject*) &SiginfoType); - PyModule_AddObject(m, "struct_siginfo", (PyObject*) &SiginfoType); - initialized = 1; + Py_INCREF(state->SiginfoType); + PyModule_AddObject(m, "struct_siginfo", state->SiginfoType); + state->initialized = 1; #endif /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); - x = DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL); + x = state->DefaultHandler = PyLong_FromVoidPtr((void *)SIG_DFL); if (!x || PyDict_SetItemString(d, "SIG_DFL", x) < 0) goto finally; - x = IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN); + x = state->IgnoreHandler = PyLong_FromVoidPtr((void *)SIG_IGN); if (!x || PyDict_SetItemString(d, "SIG_IGN", x) < 0) goto finally; @@ -1005,10 +1073,10 @@ goto finally; #endif - x = IntHandler = PyDict_GetItemString(d, "default_int_handler"); + x = state->IntHandler = PyDict_GetItemString(d, "default_int_handler"); if (!x) goto finally; - Py_INCREF(IntHandler); + Py_INCREF(state->IntHandler); Handlers[0].tripped = 0; for (i = 1; i < NSIG; i++) { @@ -1016,18 +1084,18 @@ t = PyOS_getsig(i); Handlers[i].tripped = 0; if (t == SIG_DFL) - Handlers[i].func = DefaultHandler; + Handlers[i].func = state->DefaultHandler; else if (t == SIG_IGN) - Handlers[i].func = IgnoreHandler; + Handlers[i].func = state->IgnoreHandler; else Handlers[i].func = Py_None; /* None of our business */ Py_INCREF(Handlers[i].func); } - if (Handlers[SIGINT].func == DefaultHandler) { + if (Handlers[SIGINT].func == state->DefaultHandler) { /* Install default int handler */ - Py_INCREF(IntHandler); + Py_INCREF(state->IntHandler); Py_DECREF(Handlers[SIGINT].func); - Handlers[SIGINT].func = IntHandler; + Handlers[SIGINT].func = state->IntHandler; old_siginthandler = PyOS_setsig(SIGINT, signal_handler); } @@ -1239,10 +1307,10 @@ #endif #if defined (HAVE_SETITIMER) || defined (HAVE_GETITIMER) - ItimerError = PyErr_NewException("signal.ItimerError", - PyExc_IOError, NULL); - if (ItimerError != NULL) - PyDict_SetItemString(d, "ItimerError", ItimerError); + state->ItimerError = PyErr_NewException("signal.ItimerError", + PyExc_IOError, NULL); + if (state->ItimerError != NULL) + PyDict_SetItemString(d, "ItimerError", state->ItimerError); #endif #ifdef CTRL_C_EVENT @@ -1285,17 +1353,17 @@ Handlers[i].tripped = 0; Handlers[i].func = NULL; if (i != SIGINT && func != NULL && func != Py_None && - func != DefaultHandler && func != IgnoreHandler) + func != signalstate_global->DefaultHandler && func != signalstate_global->IgnoreHandler) PyOS_setsig(i, SIG_DFL); Py_XDECREF(func); } - Py_XDECREF(IntHandler); - IntHandler = NULL; - Py_XDECREF(DefaultHandler); - DefaultHandler = NULL; - Py_XDECREF(IgnoreHandler); - IgnoreHandler = NULL; + Py_XDECREF(signalstate_global->IntHandler); + signalstate_global->IntHandler = NULL; + Py_XDECREF(signalstate_global->DefaultHandler); + signalstate_global->DefaultHandler = NULL; + Py_XDECREF(signalstate_global->IgnoreHandler); + signalstate_global->IgnoreHandler = NULL; }