gh-76785: Simplify Channels XID Types (gh-116318)

I had added an extra cleanup abstraction a while back that has turned out to be unnecessary.
This commit is contained in:
Eric Snow 2024-03-04 12:32:39 -07:00 committed by GitHub
parent ffed8d985b
commit 01440d3a39
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -93,38 +93,6 @@ API.. The module does not create any objects that are shared globally.
PyMem_RawFree(VAR) 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_IGNORE_EXC 1
#define XID_FREE 2 #define XID_FREE 2
@ -223,28 +191,6 @@ add_new_exception(PyObject *mod, const char *name, PyObject *base)
#define ADD_NEW_EXCEPTION(MOD, NAME, BASE) \ #define ADD_NEW_EXCEPTION(MOD, NAME, BASE) \
add_new_exception(MOD, MODULE_NAME_STR "." Py_STRINGIFY(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 static int
wait_for_lock(PyThread_type_lock mutex, PY_TIMEOUT_T timeout) wait_for_lock(PyThread_type_lock mutex, PY_TIMEOUT_T timeout)
{ {
@ -269,8 +215,6 @@ wait_for_lock(PyThread_type_lock mutex, PY_TIMEOUT_T timeout)
/* module state *************************************************************/ /* module state *************************************************************/
typedef struct { typedef struct {
struct xid_class_registry xid_classes;
/* Added at runtime by interpreters module. */ /* Added at runtime by interpreters module. */
PyTypeObject *send_channel_type; PyTypeObject *send_channel_type;
PyTypeObject *recv_channel_type; PyTypeObject *recv_channel_type;
@ -332,19 +276,33 @@ traverse_module_state(module_state *state, visitproc visit, void *arg)
return 0; return 0;
} }
static void
clear_xid_types(module_state *state)
{
/* 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->ChannelIDType != NULL) {
(void)_PyCrossInterpreterData_UnregisterClass(state->ChannelIDType);
Py_CLEAR(state->ChannelIDType);
}
}
static int static int
clear_module_state(module_state *state) clear_module_state(module_state *state)
{ {
/* external types */ clear_xid_types(state);
Py_CLEAR(state->send_channel_type);
Py_CLEAR(state->recv_channel_type);
/* heap types */ /* heap types */
Py_CLEAR(state->ChannelInfoType); Py_CLEAR(state->ChannelInfoType);
if (state->ChannelIDType != NULL) {
(void)_PyCrossInterpreterData_UnregisterClass(state->ChannelIDType);
}
Py_CLEAR(state->ChannelIDType);
/* exceptions */ /* exceptions */
Py_CLEAR(state->ChannelError); Py_CLEAR(state->ChannelError);
@ -2614,6 +2572,25 @@ static PyType_Spec channelid_typespec = {
.slots = channelid_typeslots, .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 */ /* SendChannel and RecvChannel classes */
@ -2697,7 +2674,6 @@ set_channelend_types(PyObject *mod, PyTypeObject *send, PyTypeObject *recv)
if (state == NULL) { if (state == NULL) {
return -1; return -1;
} }
struct xid_class_registry *xid_classes = &state->xid_classes;
if (state->send_channel_type != NULL if (state->send_channel_type != NULL
|| state->recv_channel_type != NULL) || state->recv_channel_type != NULL)
@ -2707,11 +2683,15 @@ set_channelend_types(PyObject *mod, PyTypeObject *send, PyTypeObject *recv)
} }
state->send_channel_type = (PyTypeObject *)Py_NewRef(send); state->send_channel_type = (PyTypeObject *)Py_NewRef(send);
state->recv_channel_type = (PyTypeObject *)Py_NewRef(recv); state->recv_channel_type = (PyTypeObject *)Py_NewRef(recv);
if (ensure_xid_class(send, _channelend_shared) < 0) {
if (register_xid_class(send, _channelend_shared, xid_classes)) { Py_CLEAR(state->send_channel_type);
Py_CLEAR(state->recv_channel_type);
return -1; 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; return -1;
} }
@ -3294,13 +3274,11 @@ module_exec(PyObject *mod)
if (_globals_init() != 0) { if (_globals_init() != 0) {
return -1; return -1;
} }
struct xid_class_registry *xid_classes = NULL;
module_state *state = get_module_state(mod); module_state *state = get_module_state(mod);
if (state == NULL) { if (state == NULL) {
goto error; goto error;
} }
xid_classes = &state->xid_classes;
/* Add exception types */ /* Add exception types */
if (exceptions_init(mod) != 0) { if (exceptions_init(mod) != 0) {
@ -3319,8 +3297,7 @@ module_exec(PyObject *mod)
} }
// ChannelID // ChannelID
state->ChannelIDType = add_new_type( state->ChannelIDType = add_channelid_type(mod);
mod, &channelid_typespec, _channelid_shared, xid_classes);
if (state->ChannelIDType == NULL) { if (state->ChannelIDType == NULL) {
goto error; goto error;
} }
@ -3332,8 +3309,8 @@ module_exec(PyObject *mod)
return 0; return 0;
error: error:
if (xid_classes != NULL) { if (state != NULL) {
clear_xid_class_registry(xid_classes); clear_xid_types(state);
} }
_globals_fini(); _globals_fini();
return -1; return -1;
@ -3360,9 +3337,6 @@ module_clear(PyObject *mod)
module_state *state = get_module_state(mod); module_state *state = get_module_state(mod);
assert(state != NULL); 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. // Now we clear the module state.
clear_module_state(state); clear_module_state(state);
return 0; return 0;
@ -3374,9 +3348,6 @@ module_free(void *mod)
module_state *state = get_module_state(mod); module_state *state = get_module_state(mod);
assert(state != NULL); 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. // Now we clear the module state.
clear_module_state(state); clear_module_state(state);