@@ -63,15 +63,13 @@ atexit_cleanup(atexitmodule_state *modstate)
6363/* Installed into pylifecycle.c's atexit mechanism */
6464
6565static void
66- atexit_callfuncs (void )
66+ atexit_callfuncs (PyObject * module )
6767{
6868 PyObject * exc_type = NULL , * exc_value , * exc_tb , * r ;
6969 atexit_callback * cb ;
70- PyObject * module ;
7170 atexitmodule_state * modstate ;
7271 int i ;
7372
74- module = PyState_FindModule (& atexitmodule );
7573 if (module == NULL )
7674 return ;
7775 modstate = GET_ATEXIT_STATE (module );
@@ -185,7 +183,7 @@ Run all registered exit functions.");
185183static PyObject *
186184atexit_run_exitfuncs (PyObject * self , PyObject * unused )
187185{
188- atexit_callfuncs ();
186+ atexit_callfuncs (self );
189187 if (PyErr_Occurred ())
190188 return NULL ;
191189 Py_RETURN_NONE ;
@@ -225,13 +223,15 @@ atexit_m_traverse(PyObject *self, visitproc visit, void *arg)
225223 atexitmodule_state * modstate ;
226224
227225 modstate = GET_ATEXIT_STATE (self );
228- for (i = 0 ; i < modstate -> ncallbacks ; i ++ ) {
229- atexit_callback * cb = modstate -> atexit_callbacks [i ];
230- if (cb == NULL )
231- continue ;
232- Py_VISIT (cb -> func );
233- Py_VISIT (cb -> args );
234- Py_VISIT (cb -> kwargs );
226+ if (modstate != NULL ) {
227+ for (i = 0 ; i < modstate -> ncallbacks ; i ++ ) {
228+ atexit_callback * cb = modstate -> atexit_callbacks [i ];
229+ if (cb == NULL )
230+ continue ;
231+ Py_VISIT (cb -> func );
232+ Py_VISIT (cb -> args );
233+ Py_VISIT (cb -> kwargs );
234+ }
235235 }
236236 return 0 ;
237237}
@@ -241,7 +241,9 @@ atexit_m_clear(PyObject *self)
241241{
242242 atexitmodule_state * modstate ;
243243 modstate = GET_ATEXIT_STATE (self );
244- atexit_cleanup (modstate );
244+ if (modstate != NULL ) {
245+ atexit_cleanup (modstate );
246+ }
245247 return 0 ;
246248}
247249
@@ -250,8 +252,10 @@ atexit_free(PyObject *m)
250252{
251253 atexitmodule_state * modstate ;
252254 modstate = GET_ATEXIT_STATE (m );
253- atexit_cleanup (modstate );
254- PyMem_Free (modstate -> atexit_callbacks );
255+ if (modstate != NULL ) {
256+ atexit_cleanup (modstate );
257+ PyMem_Free (modstate -> atexit_callbacks );
258+ }
255259}
256260
257261PyDoc_STRVAR (atexit_unregister__doc__ ,
@@ -310,14 +314,34 @@ upon normal program termination.\n\
310314Two public functions, register and unregister, are defined.\n\
311315" );
312316
317+ static int
318+ atexit_exec (PyObject * m ) {
319+ atexitmodule_state * modstate ;
320+
321+ modstate = GET_ATEXIT_STATE (m );
322+ modstate -> callback_len = 32 ;
323+ modstate -> ncallbacks = 0 ;
324+ modstate -> atexit_callbacks = PyMem_New (atexit_callback * ,
325+ modstate -> callback_len );
326+ if (modstate -> atexit_callbacks == NULL )
327+ return -1 ;
328+
329+ _Py_PyAtExit (atexit_callfuncs , m );
330+ return 0 ;
331+ }
332+
333+ static PyModuleDef_Slot atexit_slots [] = {
334+ {Py_mod_exec , atexit_exec },
335+ {0 , NULL }
336+ };
313337
314338static struct PyModuleDef atexitmodule = {
315339 PyModuleDef_HEAD_INIT ,
316340 "atexit" ,
317341 atexit__doc__ ,
318342 sizeof (atexitmodule_state ),
319343 atexit_methods ,
320- NULL ,
344+ atexit_slots ,
321345 atexit_m_traverse ,
322346 atexit_m_clear ,
323347 (freefunc )atexit_free
@@ -326,21 +350,5 @@ static struct PyModuleDef atexitmodule = {
326350PyMODINIT_FUNC
327351PyInit_atexit (void )
328352{
329- PyObject * m ;
330- atexitmodule_state * modstate ;
331-
332- m = PyModule_Create (& atexitmodule );
333- if (m == NULL )
334- return NULL ;
335-
336- modstate = GET_ATEXIT_STATE (m );
337- modstate -> callback_len = 32 ;
338- modstate -> ncallbacks = 0 ;
339- modstate -> atexit_callbacks = PyMem_New (atexit_callback * ,
340- modstate -> callback_len );
341- if (modstate -> atexit_callbacks == NULL )
342- return NULL ;
343-
344- _Py_PyAtExit (atexit_callfuncs );
345- return m ;
353+ return PyModuleDef_Init (& atexitmodule );
346354}
0 commit comments