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

`}

`