aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Modules/atexitmodule.c
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.com>2024-02-12 07:53:52 +0300
committerDaniil Cherednik <dcherednik@ydb.tech>2024-02-14 14:26:16 +0000
commit31f2a419764a8ba77c2a970cfc80056c6cd06756 (patch)
treec1995d239eba8571cefc640f6648e1d5dd4ce9e2 /contrib/tools/python3/src/Modules/atexitmodule.c
parentfe2ef02b38d9c85d80060963b265a1df9f38c3bb (diff)
downloadydb-31f2a419764a8ba77c2a970cfc80056c6cd06756.tar.gz
Update Python from 3.11.8 to 3.12.2
Diffstat (limited to 'contrib/tools/python3/src/Modules/atexitmodule.c')
-rw-r--r--contrib/tools/python3/src/Modules/atexitmodule.c63
1 files changed, 54 insertions, 9 deletions
diff --git a/contrib/tools/python3/src/Modules/atexitmodule.c b/contrib/tools/python3/src/Modules/atexitmodule.c
index a1c511e09d..5882d40563 100644
--- a/contrib/tools/python3/src/Modules/atexitmodule.c
+++ b/contrib/tools/python3/src/Modules/atexitmodule.c
@@ -7,6 +7,7 @@
*/
#include "Python.h"
+#include "pycore_atexit.h"
#include "pycore_initconfig.h" // _PyStatus_NO_MEMORY
#include "pycore_interp.h" // PyInterpreterState.atexit
#include "pycore_pystate.h" // _PyInterpreterState_GET
@@ -22,10 +23,36 @@ get_atexit_state(void)
}
+int
+_Py_AtExit(PyInterpreterState *interp,
+ atexit_datacallbackfunc func, void *data)
+{
+ assert(interp == _PyInterpreterState_GET());
+ atexit_callback *callback = PyMem_Malloc(sizeof(atexit_callback));
+ if (callback == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ callback->func = func;
+ callback->data = data;
+ callback->next = NULL;
+
+ struct atexit_state *state = &interp->atexit;
+ if (state->ll_callbacks == NULL) {
+ state->ll_callbacks = callback;
+ state->last_ll_callback = callback;
+ }
+ else {
+ state->last_ll_callback->next = callback;
+ }
+ return 0;
+}
+
+
static void
atexit_delete_cb(struct atexit_state *state, int i)
{
- atexit_callback *cb = state->callbacks[i];
+ atexit_py_callback *cb = state->callbacks[i];
state->callbacks[i] = NULL;
Py_DECREF(cb->func);
@@ -39,7 +66,7 @@ atexit_delete_cb(struct atexit_state *state, int i)
static void
atexit_cleanup(struct atexit_state *state)
{
- atexit_callback *cb;
+ atexit_py_callback *cb;
for (int i = 0; i < state->ncallbacks; i++) {
cb = state->callbacks[i];
if (cb == NULL)
@@ -60,7 +87,7 @@ _PyAtExit_Init(PyInterpreterState *interp)
state->callback_len = 32;
state->ncallbacks = 0;
- state->callbacks = PyMem_New(atexit_callback*, state->callback_len);
+ state->callbacks = PyMem_New(atexit_py_callback*, state->callback_len);
if (state->callbacks == NULL) {
return _PyStatus_NO_MEMORY();
}
@@ -75,6 +102,18 @@ _PyAtExit_Fini(PyInterpreterState *interp)
atexit_cleanup(state);
PyMem_Free(state->callbacks);
state->callbacks = NULL;
+
+ atexit_callback *next = state->ll_callbacks;
+ state->ll_callbacks = NULL;
+ while (next != NULL) {
+ atexit_callback *callback = next;
+ next = callback->next;
+ atexit_datacallbackfunc exitfunc = callback->func;
+ void *data = callback->data;
+ // It was allocated in _PyAtExit_AddCallback().
+ PyMem_Free(callback);
+ exitfunc(data);
+ }
}
@@ -88,7 +127,7 @@ atexit_callfuncs(struct atexit_state *state)
}
for (int i = state->ncallbacks - 1; i >= 0; i--) {
- atexit_callback *cb = state->callbacks[i];
+ atexit_py_callback *cb = state->callbacks[i];
if (cb == NULL) {
continue;
}
@@ -152,17 +191,17 @@ atexit_register(PyObject *module, PyObject *args, PyObject *kwargs)
struct atexit_state *state = get_atexit_state();
if (state->ncallbacks >= state->callback_len) {
- atexit_callback **r;
+ atexit_py_callback **r;
state->callback_len += 16;
- size_t size = sizeof(atexit_callback*) * (size_t)state->callback_len;
- r = (atexit_callback**)PyMem_Realloc(state->callbacks, size);
+ size_t size = sizeof(atexit_py_callback*) * (size_t)state->callback_len;
+ r = (atexit_py_callback**)PyMem_Realloc(state->callbacks, size);
if (r == NULL) {
return PyErr_NoMemory();
}
state->callbacks = r;
}
- atexit_callback *callback = PyMem_Malloc(sizeof(atexit_callback));
+ atexit_py_callback *callback = PyMem_Malloc(sizeof(atexit_py_callback));
if (callback == NULL) {
return PyErr_NoMemory();
}
@@ -233,7 +272,7 @@ atexit_unregister(PyObject *module, PyObject *func)
struct atexit_state *state = get_atexit_state();
for (int i = 0; i < state->ncallbacks; i++)
{
- atexit_callback *cb = state->callbacks[i];
+ atexit_py_callback *cb = state->callbacks[i];
if (cb == NULL) {
continue;
}
@@ -275,12 +314,18 @@ upon normal program termination.\n\
Two public functions, register and unregister, are defined.\n\
");
+static PyModuleDef_Slot atexitmodule_slots[] = {
+ {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
+ {0, NULL}
+};
+
static struct PyModuleDef atexitmodule = {
PyModuleDef_HEAD_INIT,
.m_name = "atexit",
.m_doc = atexit__doc__,
.m_size = 0,
.m_methods = atexit_methods,
+ .m_slots = atexitmodule_slots,
};
PyMODINIT_FUNC