bpo-42639: Move atexit state to PyInterpreterState (GH-23763) · python/cpython@b8fa135

@@ -7,38 +7,26 @@

77

*/

8899

#include "Python.h"

10-

#include "pycore_interp.h" // PyInterpreterState.atexit_func

10+

#include "pycore_initconfig.h" // _PyStatus_NO_MEMORY

11+

#include "pycore_interp.h" // PyInterpreterState.atexit

1112

#include "pycore_pystate.h" // _PyInterpreterState_GET

12131314

/* ===================================================================== */

1415

/* Callback machinery. */

151616-

typedef struct {

17-

PyObject *func;

18-

PyObject *args;

19-

PyObject *kwargs;

20-

} atexit_callback;

21-22-

struct atexit_state {

23-

atexit_callback **atexit_callbacks;

24-

int ncallbacks;

25-

int callback_len;

26-

};

27-2817

static inline struct atexit_state*

29-

get_atexit_state(PyObject *module)

18+

get_atexit_state(void)

3019

{

31-

void *state = PyModule_GetState(module);

32-

assert(state != NULL);

33-

return (struct atexit_state *)state;

20+

PyInterpreterState *interp = _PyInterpreterState_GET();

21+

return &interp->atexit;

3422

}

352336243725

static void

3826

atexit_delete_cb(struct atexit_state *state, int i)

3927

{

40-

atexit_callback *cb = state->atexit_callbacks[i];

41-

state->atexit_callbacks[i] = NULL;

28+

atexit_callback *cb = state->callbacks[i];

29+

state->callbacks[i] = NULL;

42304331

Py_DECREF(cb->func);

4432

Py_DECREF(cb->args);

@@ -53,7 +41,7 @@ atexit_cleanup(struct atexit_state *state)

5341

{

5442

atexit_callback *cb;

5543

for (int i = 0; i < state->ncallbacks; i++) {

56-

cb = state->atexit_callbacks[i];

44+

cb = state->callbacks[i];

5745

if (cb == NULL)

5846

continue;

5947

@@ -62,25 +50,45 @@ atexit_cleanup(struct atexit_state *state)

6250

state->ncallbacks = 0;

6351

}

645265-

/* Installed into pylifecycle.c's atexit mechanism */

665367-

static void

68-

atexit_callfuncs(PyObject *module, int ignore_exc)

54+

PyStatus

55+

_PyAtExit_Init(PyThreadState *tstate)

6956

{

70-

assert(!PyErr_Occurred());

57+

struct atexit_state *state = &tstate->interp->atexit;

58+

// _PyAtExit_Init() must only be called once

59+

assert(state->callbacks == NULL);

716072-

if (module == NULL) {

73-

return;

61+

state->callback_len = 32;

62+

state->ncallbacks = 0;

63+

state->callbacks = PyMem_New(atexit_callback*, state->callback_len);

64+

if (state->callbacks == NULL) {

65+

return _PyStatus_NO_MEMORY();

7466

}

67+

return _PyStatus_OK();

68+

}

69+70+71+

void

72+

_PyAtExit_Fini(PyInterpreterState *interp)

73+

{

74+

struct atexit_state *state = &interp->atexit;

75+

atexit_cleanup(state);

76+

PyMem_Free(state->callbacks);

77+

}

78+79+80+

static void

81+

atexit_callfuncs(struct atexit_state *state, int ignore_exc)

82+

{

83+

assert(!PyErr_Occurred());

758476-

struct atexit_state *state = get_atexit_state(module);

7785

if (state->ncallbacks == 0) {

7886

return;

7987

}

80888189

PyObject *exc_type = NULL, *exc_value, *exc_tb;

8290

for (int i = state->ncallbacks - 1; i >= 0; i--) {

83-

atexit_callback *cb = state->atexit_callbacks[i];

91+

atexit_callback *cb = state->callbacks[i];

8492

if (cb == NULL) {

8593

continue;

8694

}

@@ -125,15 +133,17 @@ atexit_callfuncs(PyObject *module, int ignore_exc)

125133126134127135

void

128-

_PyAtExit_Call(PyObject *module)

136+

_PyAtExit_Call(PyThreadState *tstate)

129137

{

130-

atexit_callfuncs(module, 1);

138+

struct atexit_state *state = &tstate->interp->atexit;

139+

atexit_callfuncs(state, 1);

131140

}

132141133142134143

/* ===================================================================== */

135144

/* Module methods. */

136145146+137147

PyDoc_STRVAR(atexit_register__doc__,

138148

"register(func, *args, **kwargs) -> func\n\

139149

\n\

@@ -161,15 +171,15 @@ atexit_register(PyObject *module, PyObject *args, PyObject *kwargs)

161171

return NULL;

162172

}

163173164-

struct atexit_state *state = get_atexit_state(module);

174+

struct atexit_state *state = get_atexit_state();

165175

if (state->ncallbacks >= state->callback_len) {

166176

atexit_callback **r;

167177

state->callback_len += 16;

168-

r = (atexit_callback**)PyMem_Realloc(state->atexit_callbacks,

169-

sizeof(atexit_callback*) * state->callback_len);

178+

size_t size = sizeof(atexit_callback*) * (size_t)state->callback_len;

179+

r = (atexit_callback**)PyMem_Realloc(state->callbacks, size);

170180

if (r == NULL)

171181

return PyErr_NoMemory();

172-

state->atexit_callbacks = r;

182+

state->callbacks = r;

173183

}

174184175185

atexit_callback *callback = PyMem_Malloc(sizeof(atexit_callback));

@@ -185,7 +195,7 @@ atexit_register(PyObject *module, PyObject *args, PyObject *kwargs)

185195

callback->func = Py_NewRef(func);

186196

callback->kwargs = Py_XNewRef(kwargs);

187197188-

state->atexit_callbacks[state->ncallbacks++] = callback;

198+

state->callbacks[state->ncallbacks++] = callback;

189199190200

return Py_NewRef(func);

191201

}

@@ -198,7 +208,8 @@ Run all registered exit functions.");

198208

static PyObject *

199209

atexit_run_exitfuncs(PyObject *module, PyObject *unused)

200210

{

201-

atexit_callfuncs(module, 0);

211+

struct atexit_state *state = get_atexit_state();

212+

atexit_callfuncs(state, 0);

202213

if (PyErr_Occurred()) {

203214

return NULL;

204215

}

@@ -213,7 +224,7 @@ Clear the list of previously registered exit functions.");

213224

static PyObject *

214225

atexit_clear(PyObject *module, PyObject *unused)

215226

{

216-

atexit_cleanup(get_atexit_state(module));

227+

atexit_cleanup(get_atexit_state());

217228

Py_RETURN_NONE;

218229

}

219230

@@ -225,41 +236,10 @@ Return the number of registered exit functions.");

225236

static PyObject *

226237

atexit_ncallbacks(PyObject *module, PyObject *unused)

227238

{

228-

struct atexit_state *state = get_atexit_state(module);

239+

struct atexit_state *state = get_atexit_state();

229240

return PyLong_FromSsize_t(state->ncallbacks);

230241

}

231242232-

static int

233-

atexit_m_traverse(PyObject *module, visitproc visit, void *arg)

234-

{

235-

struct atexit_state *state = (struct atexit_state *)PyModule_GetState(module);

236-

for (int i = 0; i < state->ncallbacks; i++) {

237-

atexit_callback *cb = state->atexit_callbacks[i];

238-

if (cb == NULL)

239-

continue;

240-

Py_VISIT(cb->func);

241-

Py_VISIT(cb->args);

242-

Py_VISIT(cb->kwargs);

243-

}

244-

return 0;

245-

}

246-247-

static int

248-

atexit_m_clear(PyObject *module)

249-

{

250-

struct atexit_state *state = (struct atexit_state *)PyModule_GetState(module);

251-

atexit_cleanup(state);

252-

return 0;

253-

}

254-255-

static void

256-

atexit_free(PyObject *module)

257-

{

258-

struct atexit_state *state = (struct atexit_state *)PyModule_GetState(module);

259-

atexit_cleanup(state);

260-

PyMem_Free(state->atexit_callbacks);

261-

}

262-263243

PyDoc_STRVAR(atexit_unregister__doc__,

264244

"unregister(func) -> None\n\

265245

\n\

@@ -271,10 +251,10 @@ atexit.register\n\

271251

static PyObject *

272252

atexit_unregister(PyObject *module, PyObject *func)

273253

{

274-

struct atexit_state *state = get_atexit_state(module);

254+

struct atexit_state *state = get_atexit_state();

275255

for (int i = 0; i < state->ncallbacks; i++)

276256

{

277-

atexit_callback *cb = state->atexit_callbacks[i];

257+

atexit_callback *cb = state->callbacks[i];

278258

if (cb == NULL) {

279259

continue;

280260

}

@@ -305,6 +285,7 @@ static PyMethodDef atexit_methods[] = {

305285

{NULL, NULL} /* sentinel */

306286

};

307287288+308289

/* ===================================================================== */

309290

/* Initialization function. */

310291

@@ -315,37 +296,12 @@ upon normal program termination.\n\

315296

Two public functions, register and unregister, are defined.\n\

316297

");

317298318-

static int

319-

atexit_exec(PyObject *module)

320-

{

321-

struct atexit_state *state = get_atexit_state(module);

322-

state->callback_len = 32;

323-

state->ncallbacks = 0;

324-

state->atexit_callbacks = PyMem_New(atexit_callback*, state->callback_len);

325-

if (state->atexit_callbacks == NULL) {

326-

return -1;

327-

}

328-329-

PyInterpreterState *interp = _PyInterpreterState_GET();

330-

interp->atexit_module = module;

331-

return 0;

332-

}

333-334-

static PyModuleDef_Slot atexit_slots[] = {

335-

{Py_mod_exec, atexit_exec},

336-

{0, NULL}

337-

};

338-339299

static struct PyModuleDef atexitmodule = {

340300

PyModuleDef_HEAD_INIT,

341301

.m_name = "atexit",

342302

.m_doc = atexit__doc__,

343-

.m_size = sizeof(struct atexit_state),

303+

.m_size = 0,

344304

.m_methods = atexit_methods,

345-

.m_slots = atexit_slots,

346-

.m_traverse = atexit_m_traverse,

347-

.m_clear = atexit_m_clear,

348-

.m_free = (freefunc)atexit_free

349305

};

350306351307

PyMODINIT_FUNC