8000 gh-76785: Simplify Channels XID Types by ericsnowcurrently · Pull Request #116318 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-76785: Simplify Channels XID Types #116318

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 49 additions & 78 deletions Modules/_xxinterpchannelsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -223,28 +191,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)
{
Expand All @@ -269,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;
Expand Down Expand Up @@ -332,19 +276,33 @@ 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)
{
/* external types */
Py_CLEAR(state->send_channel_type);
Py_CLEAR(state->recv_channel_type);
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 */
Py_CLEAR(state->ChannelInfoType);
if (state->ChannelIDType != NULL) {
(void)_PyCrossInterpreterData_UnregisterClass(state->ChannelIDType);
Py_CLEAR(state->ChannelIDType);
}
Py_CLEAR(state->ChannelIDType);
}

static int
clear_module_state(module_state *state)
{
clear_xid_types(state);

/* heap types */
Py_CLEAR(state->ChannelInfoType);

/* exceptions */
Py_CLEAR(state->ChannelError);
Expand Down Expand Up @@ -2614,6 +2572,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 */

Expand Down Expand Up @@ -2697,7 +2674,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)
Expand All @@ -2707,11 +2683,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;
}

Expand Down Expand Up @@ -3294,13 +3274,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) {
Expand All @@ -3319,8 +3297,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;
}
Expand All @@ -3332,8 +3309,8 @@ module_exec(PyObject *mod)
return 0;

error:
if (xid_classes != NULL) {
clear_xid_class_registry(xid_classes);
if (state != NULL) {
clear_xid_types(state);
}
_globals_fini();
return -1;
Expand All @@ -3360,9 +3337,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;
Expand All @@ -3374,9 +3348,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);

Expand Down
0