From 6cb18f40e406ce32e847accd0a743d0ced070504 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 15 Feb 2024 11:24:22 -0700 Subject: [PATCH 1/5] add_new_type() -> add_channelid_type() --- Modules/_xxinterpchannelsmodule.c | 51 ++++++++++++++----------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/Modules/_xxinterpchannelsmodule.c b/Modules/_xxinterpchannelsmodule.c index 82d2ae7fc4c963..fea2b306357a2d 100644 --- a/Modules/_xxinterpchannelsmodule.c +++ b/Modules/_xxinterpchannelsmodule.c @@ -223,28 +223,6 @@ add_new_exception(PyObject *mod, const char *name, PyObject *base) #define ADD_NEW_EXCEPTION(MOD, NAME, BASE) \ add_new_exception(MOD, MODULE_NAME_STR "." Py_STRINGIFY(NAME), BASE) -static PyTypeObject * -add_new_type(PyObject *mod, PyType_Spec *spec, crossinterpdatafunc shared, - struct xid_class_registry *classes) -{ - PyTypeObject *cls = (PyTypeObject *)PyType_FromModuleAndSpec( - mod, spec, NULL); - if (cls == NULL) { - return NULL; - } - if (PyModule_AddType(mod, cls) < 0) { - Py_DECREF(cls); - return NULL; - } - if (shared != NULL) { - if (register_xid_class(cls, shared, classes)) { - Py_DECREF(cls); - return NULL; - } - } - return cls; -} - static int wait_for_lock(PyThread_type_lock mutex, PY_TIMEOUT_T timeout) { @@ -2614,6 +2592,25 @@ static PyType_Spec channelid_typespec = { .slots = channelid_typeslots, }; +static PyTypeObject * +add_channelid_type(PyObject *mod) +{ + PyTypeObject *cls = (PyTypeObject *)PyType_FromModuleAndSpec( + mod, &channelid_typespec, NULL); + if (cls == NULL) { + return NULL; + } + if (PyModule_AddType(mod, cls) < 0) { + Py_DECREF(cls); + return NULL; + } + if (ensure_xid_class(cls, _channelid_shared) < 0) { + Py_DECREF(cls); + return NULL; + } + return cls; +} + /* SendChannel and RecvChannel classes */ @@ -3294,13 +3291,11 @@ module_exec(PyObject *mod) if (_globals_init() != 0) { return -1; } - struct xid_class_registry *xid_classes = NULL; module_state *state = get_module_state(mod); if (state == NULL) { goto error; } - xid_classes = &state->xid_classes; /* Add exception types */ if (exceptions_init(mod) != 0) { @@ -3319,8 +3314,7 @@ module_exec(PyObject *mod) } // ChannelID - state->ChannelIDType = add_new_type( - mod, &channelid_typespec, _channelid_shared, xid_classes); + state->ChannelIDType = add_channelid_type(mod); if (state->ChannelIDType == NULL) { goto error; } @@ -3332,8 +3326,9 @@ module_exec(PyObject *mod) return 0; error: - if (xid_classes != NULL) { - clear_xid_class_registry(xid_classes); + if (state->ChannelInfoType != NULL) { + (void)_PyCrossInterpreterData_UnregisterClass(state->ChannelInfoType); + Py_CLEAR(state->ChannelInfoType); } _globals_fini(); return -1; From f5d0db8adfcbc158bdbc2d561b307ef0ec9c211e Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 15 Feb 2024 11:27:29 -0700 Subject: [PATCH 2/5] Add clear_xid_types(). --- Modules/_xxinterpchannelsmodule.c | 32 ++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/Modules/_xxinterpchannelsmodule.c b/Modules/_xxinterpchannelsmodule.c index fea2b306357a2d..96ba8e33d13aef 100644 --- a/Modules/_xxinterpchannelsmodule.c +++ b/Modules/_xxinterpchannelsmodule.c @@ -310,19 +310,28 @@ traverse_module_state(module_state *state, visitproc visit, void *arg) return 0; } -static int -clear_module_state(module_state *state) +static void +clear_xid_types(module_state *state) { + /* heap types */ + if (state->ChannelInfoType != NULL) { + (void)_PyCrossInterpreterData_UnregisterClass(state->ChannelInfoType); + Py_CLEAR(state->ChannelInfoType); + } + /* external types */ + clear_xid_class_registry(&state->xid_classes); Py_CLEAR(state->send_channel_type); Py_CLEAR(state->recv_channel_type); +} + +static int +clear_module_state(module_state *state) +{ + clear_xid_types(state); /* heap types */ Py_CLEAR(state->ChannelInfoType); - if (state->ChannelIDType != NULL) { - (void)_PyCrossInterpreterData_UnregisterClass(state->ChannelIDType); - } - Py_CLEAR(state->ChannelIDType); /* exceptions */ Py_CLEAR(state->ChannelError); @@ -3326,9 +3335,8 @@ module_exec(PyObject *mod) return 0; error: - if (state->ChannelInfoType != NULL) { - (void)_PyCrossInterpreterData_UnregisterClass(state->ChannelInfoType); - Py_CLEAR(state->ChannelInfoType); + if (state != NULL) { + clear_xid_types(state); } _globals_fini(); return -1; @@ -3355,9 +3363,6 @@ module_clear(PyObject *mod) module_state *state = get_module_state(mod); assert(state != NULL); - // Before clearing anything, we unregister the various XID types. */ - clear_xid_class_registry(&state->xid_classes); - // Now we clear the module state. clear_module_state(state); return 0; @@ -3369,9 +3374,6 @@ module_free(void *mod) module_state *state = get_module_state(mod); assert(state != NULL); - // Before clearing anything, we unregister the various XID types. */ - clear_xid_class_registry(&state->xid_classes); - // Now we clear the module state. clear_module_state(state); From a3ef45a6d107670d8acc58075f3268e8ebc5a8ae Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 15 Feb 2024 11:44:40 -0700 Subject: [PATCH 3/5] Do not use the XID type registry in set_channelend_types(). --- Modules/_xxinterpchannelsmodule.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/Modules/_xxinterpchannelsmodule.c b/Modules/_xxinterpchannelsmodule.c index 96ba8e33d13aef..136ac075fb98d0 100644 --- a/Modules/_xxinterpchannelsmodule.c +++ b/Modules/_xxinterpchannelsmodule.c @@ -313,16 +313,23 @@ traverse_module_state(module_state *state, visitproc visit, void *arg) static void clear_xid_types(module_state *state) { + clear_xid_class_registry(&state->xid_classes); + + /* external types */ + if (state->send_channel_type != NULL) { + (void)_PyCrossInterpreterData_UnregisterClass(state->send_channel_type); + Py_CLEAR(state->send_channel_type); + } + if (state->recv_channel_type != NULL) { + (void)_PyCrossInterpreterData_UnregisterClass(state->recv_channel_type); + Py_CLEAR(state->recv_channel_type); + } + /* heap types */ if (state->ChannelInfoType != NULL) { (void)_PyCrossInterpreterData_UnregisterClass(state->ChannelInfoType); Py_CLEAR(state->ChannelInfoType); } - - /* external types */ - clear_xid_class_registry(&state->xid_classes); - Py_CLEAR(state->send_channel_type); - Py_CLEAR(state->recv_channel_type); } static int @@ -2703,7 +2710,6 @@ set_channelend_types(PyObject *mod, PyTypeObject *send, PyTypeObject *recv) if (state == NULL) { return -1; } - struct xid_class_registry *xid_classes = &state->xid_classes; if (state->send_channel_type != NULL || state->recv_channel_type != NULL) @@ -2713,11 +2719,15 @@ set_channelend_types(PyObject *mod, PyTypeObject *send, PyTypeObject *recv) } state->send_channel_type = (PyTypeObject *)Py_NewRef(send); state->recv_channel_type = (PyTypeObject *)Py_NewRef(recv); - - if (register_xid_class(send, _channelend_shared, xid_classes)) { + if (ensure_xid_class(send, _channelend_shared) < 0) { + Py_CLEAR(state->send_channel_type); + Py_CLEAR(state->recv_channel_type); return -1; } - if (register_xid_class(recv, _channelend_shared, xid_classes)) { + if (ensure_xid_class(recv, _channelend_shared) < 0) { + (void)_PyCrossInterpreterData_UnregisterClass(state->send_channel_type); + Py_CLEAR(state->send_channel_type); + Py_CLEAR(state->recv_channel_type); return -1; } From db9d92cc9034a5325362310bfde8ec36f3690b8f Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Thu, 15 Feb 2024 11:50:29 -0700 Subject: [PATCH 4/5] Drop the XID type registry. --- Modules/_xxinterpchannelsmodule.c | 36 ------------------------------- 1 file changed, 36 deletions(-) diff --git a/Modules/_xxinterpchannelsmodule.c b/Modules/_xxinterpchannelsmodule.c index 136ac075fb98d0..cc386ee4f084d5 100644 --- a/Modules/_xxinterpchannelsmodule.c +++ b/Modules/_xxinterpchannelsmodule.c @@ -93,38 +93,6 @@ API.. The module does not create any objects that are shared globally. PyMem_RawFree(VAR) -struct xid_class_registry { - size_t count; -#define MAX_XID_CLASSES 5 - struct { - PyTypeObject *cls; - } added[MAX_XID_CLASSES]; -}; - -static int -register_xid_class(PyTypeObject *cls, crossinterpdatafunc shared, - struct xid_class_registry *classes) -{ - int res = ensure_xid_class(cls, shared); - if (res == 0) { - assert(classes->count < MAX_XID_CLASSES); - // The class has refs elsewhere, so we need to incref here. - classes->added[classes->count].cls = cls; - classes->count += 1; - } - return res; -} - -static void -clear_xid_class_registry(struct xid_class_registry *classes) -{ - while (classes->count > 0) { - classes->count -= 1; - PyTypeObject *cls = classes->added[classes->count].cls; - _PyCrossInterpreterData_UnregisterClass(cls); - } -} - #define XID_IGNORE_EXC 1 #define XID_FREE 2 @@ -247,8 +215,6 @@ wait_for_lock(PyThread_type_lock mutex, PY_TIMEOUT_T timeout) /* module state *************************************************************/ typedef struct { - struct xid_class_registry xid_classes; - /* Added at runtime by interpreters module. */ PyTypeObject *send_channel_type; PyTypeObject *recv_channel_type; @@ -313,8 +279,6 @@ traverse_module_state(module_state *state, visitproc visit, void *arg) static void clear_xid_types(module_state *state) { - clear_xid_class_registry(&state->xid_classes); - /* external types */ if (state->send_channel_type != NULL) { (void)_PyCrossInterpreterData_UnregisterClass(state->send_channel_type); From 970d88b079befbbb9823113de2f9218a4c154c19 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 4 Mar 2024 11:56:57 -0700 Subject: [PATCH 5/5] Clear the right class. --- Modules/_xxinterpchannelsmodule.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/_xxinterpchannelsmodule.c b/Modules/_xxinterpchannelsmodule.c index cc386ee4f084d5..c0d4fd08088434 100644 --- a/Modules/_xxinterpchannelsmodule.c +++ b/Modules/_xxinterpchannelsmodule.c @@ -290,9 +290,9 @@ clear_xid_types(module_state *state) } /* heap types */ - if (state->ChannelInfoType != NULL) { - (void)_PyCrossInterpreterData_UnregisterClass(state->ChannelInfoType); - Py_CLEAR(state->ChannelInfoType); + if (state->ChannelIDType != NULL) { + (void)_PyCrossInterpreterData_UnregisterClass(state->ChannelIDType); + Py_CLEAR(state->ChannelIDType); } }