diff -r df15b52438a8 Modules/fpectlmodule.c --- a/Modules/fpectlmodule.c Thu Aug 16 10:24:01 2012 +0200 +++ b/Modules/fpectlmodule.c Thu Aug 16 10:29:49 2012 +0200 @@ -81,15 +81,46 @@ * the limited control to induce a core dump in case of an exception. */ #include -static jmp_buf PyFPE_jbuf; -static int PyFPE_counter = 0; #endif typedef void Sigfunc(int); static Sigfunc sigfpe_handler; static void fpe_reset(Sigfunc *); -static PyObject *fpe_error; +typedef struct { + PyObject *fpe_error; + #ifdef WANT_SIGFPE_HANDLER + jmp_buf PyFPE_jbuf; + int PyFPE_counter; + #endif +} fpectlstate; + +#define fpectl_state(o) ((fpectlstate *)PyModule_GetState(o)) + +static int +fpectl_clear(PyObject *m) +{ + Py_CLEAR(fpectl_state(m)->fpe_error); + return 0; +} + +static int +fpectl_traverse(PyObject *m, visitproc visit, void *arg) +{ + Py_VISIT(fpectl_state(m)->fpe_error); + return 0; +} + +static void +fpectl_free(void *m) +{ + fpectl_clear((PyObject *)m); +} + +static PyModuleDef fpectlmodule; + +#define fpectlstate_global ((fpectlstate *)PyModule_GetState(PyState_FindModule(&fpectlmodule))) + PyMODINIT_FUNC PyInit_fpectl(void); static PyObject *turnon_sigfpe (PyObject *self,PyObject *args); @@ -269,8 +300,8 @@ static void sigfpe_handler(int signo) { fpe_reset(sigfpe_handler); - if(PyFPE_counter) { - longjmp(PyFPE_jbuf, 1); + if(fpectlstate_global->PyFPE_counter) { + longjmp(fpectlstate_global->PyFPE_jbuf, 1); } else { Py_FatalError("Unprotected floating point exception"); } @@ -280,12 +311,12 @@ PyModuleDef_HEAD_INIT, "fpectl", NULL, - -1, + sizeof(fpectlstate), fpectl_methods, NULL, - NULL, - NULL, - NULL + fpectl_traverse, + fpectl_clear, + fpectl_free }; PyMODINIT_FUNC PyInit_fpectl(void) @@ -295,9 +326,10 @@ if (m == NULL) return NULL; d = PyModule_GetDict(m); - fpe_error = PyErr_NewException("fpectl.error", NULL, NULL); - if (fpe_error != NULL) - PyDict_SetItemString(d, "error", fpe_error); + fpectl_state(m)->PyFPE_counter = 0; + fpectl_state(m)->fpe_error = PyErr_NewException("fpectl.error", NULL, NULL); + if (fpectl_state(m)->fpe_error != NULL) + PyDict_SetItemString(d, "error", fpectl_state(m)->fpe_error); return m; }