@@ -93,38 +93,6 @@ API.. The module does not create any objects that are shared globally.
9393 PyMem_RawFree(VAR)
9494
9595
96- struct xid_class_registry {
97- size_t count ;
98- #define MAX_XID_CLASSES 5
99- struct {
100- PyTypeObject * cls ;
101- } added [MAX_XID_CLASSES ];
102- };
103-
104- static int
105- register_xid_class (PyTypeObject * cls , crossinterpdatafunc shared ,
106- struct xid_class_registry * classes )
107- {
108- int res = ensure_xid_class (cls , shared );
109- if (res == 0 ) {
110- assert (classes -> count < MAX_XID_CLASSES );
111- // The class has refs elsewhere, so we need to incref here.
112- classes -> added [classes -> count ].cls = cls ;
113- classes -> count += 1 ;
114- }
115- return res ;
116- }
117-
118- static void
119- clear_xid_class_registry (struct xid_class_registry * classes )
120- {
121- while (classes -> count > 0 ) {
122- classes -> count -= 1 ;
123- PyTypeObject * cls = classes -> added [classes -> count ].cls ;
124- _PyCrossInterpreterData_UnregisterClass (cls );
125- }
126- }
127-
12896#define XID_IGNORE_EXC 1
12997#define XID_FREE 2
13098
@@ -223,28 +191,6 @@ add_new_exception(PyObject *mod, const char *name, PyObject *base)
223191#define ADD_NEW_EXCEPTION (MOD , NAME , BASE ) \
224192 add_new_exception(MOD, MODULE_NAME_STR "." Py_STRINGIFY(NAME), BASE)
225193
226- static PyTypeObject *
227- add_new_type (PyObject * mod , PyType_Spec * spec , crossinterpdatafunc shared ,
228- struct xid_class_registry * classes )
229- {
230- PyTypeObject * cls = (PyTypeObject * )PyType_FromModuleAndSpec (
231- mod , spec , NULL );
232- if (cls == NULL ) {
233- return NULL ;
234- }
235- if (PyModule_AddType (mod , cls ) < 0 ) {
236- Py_DECREF (cls );
237- return NULL ;
238- }
239- if (shared != NULL ) {
240- if (register_xid_class (cls , shared , classes )) {
241- Py_DECREF (cls );
242- return NULL ;
243- }
244- }
245- return cls ;
246- }
247-
248194static int
249195wait_for_lock (PyThread_type_lock mutex , PY_TIMEOUT_T timeout )
250196{
@@ -269,8 +215,6 @@ wait_for_lock(PyThread_type_lock mutex, PY_TIMEOUT_T timeout)
269215/* module state *************************************************************/
270216
271217typedef struct {
272- struct xid_class_registry xid_classes ;
273-
274218 /* Added at runtime by interpreters module. */
275219 PyTypeObject * send_channel_type ;
276220 PyTypeObject * recv_channel_type ;
@@ -332,19 +276,33 @@ traverse_module_state(module_state *state, visitproc visit, void *arg)
332276 return 0 ;
333277}
334278
335- static int
336- clear_module_state (module_state * state )
279+ static void
280+ clear_xid_types (module_state * state )
337281{
338282 /* external types */
339- Py_CLEAR (state -> send_channel_type );
340- Py_CLEAR (state -> recv_channel_type );
283+ if (state -> send_channel_type != NULL ) {
284+ (void )_PyCrossInterpreterData_UnregisterClass (state -> send_channel_type );
285+ Py_CLEAR (state -> send_channel_type );
286+ }
287+ if (state -> recv_channel_type != NULL ) {
288+ (void )_PyCrossInterpreterData_UnregisterClass (state -> recv_channel_type );
289+ Py_CLEAR (state -> recv_channel_type );
290+ }
341291
342292 /* heap types */
343- Py_CLEAR (state -> ChannelInfoType );
344293 if (state -> ChannelIDType != NULL ) {
345294 (void )_PyCrossInterpreterData_UnregisterClass (state -> ChannelIDType );
295+ Py_CLEAR (state -> ChannelIDType );
346296 }
347- Py_CLEAR (state -> ChannelIDType );
297+ }
298+
299+ static int
300+ clear_module_state (module_state * state )
301+ {
302+ clear_xid_types (state );
303+
304+ /* heap types */
305+ Py_CLEAR (state -> ChannelInfoType );
348306
349307 /* exceptions */
350308 Py_CLEAR (state -> ChannelError );
@@ -2614,6 +2572,25 @@ static PyType_Spec channelid_typespec = {
26142572 .slots = channelid_typeslots ,
26152573};
26162574
2575+ static PyTypeObject *
2576+ add_channelid_type (PyObject * mod )
2577+ {
2578+ PyTypeObject * cls = (PyTypeObject * )PyType_FromModuleAndSpec (
2579+ mod , & channelid_typespec , NULL );
2580+ if (cls == NULL ) {
2581+ return NULL ;
2582+ }
2583+ if (PyModule_AddType (mod , cls ) < 0 ) {
2584+ Py_DECREF (cls );
2585+ return NULL ;
2586+ }
2587+ if (ensure_xid_class (cls , _channelid_shared ) < 0 ) {
2588+ Py_DECREF (cls );
2589+ return NULL ;
2590+ }
2591+ return cls ;
2592+ }
2593+
26172594
26182595/* SendChannel and RecvChannel classes */
26192596
@@ -2697,7 +2674,6 @@ set_channelend_types(PyObject *mod, PyTypeObject *send, PyTypeObject *recv)
26972674 if (state == NULL ) {
26982675 return -1 ;
26992676 }
2700- struct xid_class_registry * xid_classes = & state -> xid_classes ;
27012677
27022678 if (state -> send_channel_type != NULL
27032679 || state -> recv_channel_type != NULL )
@@ -2707,11 +2683,15 @@ set_channelend_types(PyObject *mod, PyTypeObject *send, PyTypeObject *recv)
27072683 }
27082684 state -> send_channel_type = (PyTypeObject * )Py_NewRef (send );
27092685 state -> recv_channel_type = (PyTypeObject * )Py_NewRef (recv );
2710-
2711- if (register_xid_class (send , _channelend_shared , xid_classes )) {
2686+ if (ensure_xid_class (send , _channelend_shared ) < 0 ) {
2687+ Py_CLEAR (state -> send_channel_type );
2688+ Py_CLEAR (state -> recv_channel_type );
27122689 return -1 ;
27132690 }
2714- if (register_xid_class (recv , _channelend_shared , xid_classes )) {
2691+ if (ensure_xid_class (recv , _channelend_shared ) < 0 ) {
2692+ (void )_PyCrossInterpreterData_UnregisterClass (state -> send_channel_type );
2693+ Py_CLEAR (state -> send_channel_type );
2694+ Py_CLEAR (state -> recv_channel_type );
27152695 return -1 ;
27162696 }
27172697
@@ -3294,13 +3274,11 @@ module_exec(PyObject *mod)
32943274 if (_globals_init () != 0 ) {
32953275 return -1 ;
32963276 }
3297- struct xid_class_registry * xid_classes = NULL ;
32983277
32993278 module_state * state = get_module_state (mod );
33003279 if (state == NULL ) {
33013280 goto error ;
33023281 }
3303- xid_classes = & state -> xid_classes ;
33043282
33053283 /* Add exception types */
33063284 if (exceptions_init (mod ) != 0 ) {
@@ -3319,8 +3297,7 @@ module_exec(PyObject *mod)
33193297 }
33203298
33213299 // ChannelID
3322- state -> ChannelIDType = add_new_type (
3323- mod , & channelid_typespec , _channelid_shared , xid_classes );
3300+ state -> ChannelIDType = add_channelid_type (mod );
33243301 if (state -> ChannelIDType == NULL ) {
33253302 goto error ;
33263303 }
@@ -3332,8 +3309,8 @@ module_exec(PyObject *mod)
33323309 return 0 ;
33333310
33343311error :
3335- if (xid_classes != NULL ) {
3336- clear_xid_class_registry ( xid_classes );
3312+ if (state != NULL ) {
3313+ clear_xid_types ( state );
33373314 }
33383315 _globals_fini ();
33393316 return -1 ;
@@ -3360,9 +3337,6 @@ module_clear(PyObject *mod)
33603337 module_state * state = get_module_state (mod );
33613338 assert (state != NULL );
33623339
3363- // Before clearing anything, we unregister the various XID types. */
3364- clear_xid_class_registry (& state -> xid_classes );
3365-
33663340 // Now we clear the module state.
33673341 clear_module_state (state );
33683342 return 0 ;
@@ -3374,9 +3348,6 @@ module_free(void *mod)
33743348 module_state * state = get_module_state (mod );
33753349 assert (state != NULL );
33763350
3377- // Before clearing anything, we unregister the various XID types. */
3378- clear_xid_class_registry (& state -> xid_classes );
3379-
33803351 // Now we clear the module state.
33813352 clear_module_state (state );
33823353
0 commit comments