bpo-31901: atexit callbacks should be run at subinterpreter shutdown … · python/cpython@776407f (original) (raw)
`@@ -63,15 +63,13 @@ atexit_cleanup(atexitmodule_state *modstate)
`
63
63
`/* Installed into pylifecycle.c's atexit mechanism */
`
64
64
``
65
65
`static void
`
66
``
`-
atexit_callfuncs(void)
`
``
66
`+
atexit_callfuncs(PyObject *module)
`
67
67
`{
`
68
68
`PyObject *exc_type = NULL, *exc_value, *exc_tb, *r;
`
69
69
`atexit_callback *cb;
`
70
``
`-
PyObject *module;
`
71
70
`atexitmodule_state *modstate;
`
72
71
`int i;
`
73
72
``
74
``
`-
module = PyState_FindModule(&atexitmodule);
`
75
73
`if (module == NULL)
`
76
74
`return;
`
77
75
`modstate = GET_ATEXIT_STATE(module);
`
`@@ -185,7 +183,7 @@ Run all registered exit functions.");
`
185
183
`static PyObject *
`
186
184
`atexit_run_exitfuncs(PyObject *self, PyObject *unused)
`
187
185
`{
`
188
``
`-
atexit_callfuncs();
`
``
186
`+
atexit_callfuncs(self);
`
189
187
`if (PyErr_Occurred())
`
190
188
`return NULL;
`
191
189
`Py_RETURN_NONE;
`
`@@ -225,13 +223,15 @@ atexit_m_traverse(PyObject *self, visitproc visit, void *arg)
`
225
223
`atexitmodule_state *modstate;
`
226
224
``
227
225
`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
`+
}
`
235
235
` }
`
236
236
`return 0;
`
237
237
`}
`
`@@ -241,7 +241,9 @@ atexit_m_clear(PyObject *self)
`
241
241
`{
`
242
242
`atexitmodule_state *modstate;
`
243
243
`modstate = GET_ATEXIT_STATE(self);
`
244
``
`-
atexit_cleanup(modstate);
`
``
244
`+
if (modstate != NULL) {
`
``
245
`+
atexit_cleanup(modstate);
`
``
246
`+
}
`
245
247
`return 0;
`
246
248
`}
`
247
249
``
`@@ -250,8 +252,10 @@ atexit_free(PyObject *m)
`
250
252
`{
`
251
253
`atexitmodule_state *modstate;
`
252
254
`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
`+
}
`
255
259
`}
`
256
260
``
257
261
`PyDoc_STRVAR(atexit_unregister__doc__,
`
`@@ -310,14 +314,34 @@ upon normal program termination.\n\
`
310
314
`Two public functions, register and unregister, are defined.\n\
`
311
315
`");
`
312
316
``
``
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
`+
};
`
313
337
``
314
338
`static struct PyModuleDef atexitmodule = {
`
315
339
`PyModuleDef_HEAD_INIT,
`
316
340
`"atexit",
`
317
341
`atexit__doc__,
`
318
342
`sizeof(atexitmodule_state),
`
319
343
`atexit_methods,
`
320
``
`-
NULL,
`
``
344
`+
atexit_slots,
`
321
345
`atexit_m_traverse,
`
322
346
`atexit_m_clear,
`
323
347
` (freefunc)atexit_free
`
`@@ -326,21 +350,5 @@ static struct PyModuleDef atexitmodule = {
`
326
350
`PyMODINIT_FUNC
`
327
351
`PyInit_atexit(void)
`
328
352
`{
`
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);
`
346
354
`}
`