@@ -93,35 +93,35 @@ API.. The module does not create any objects that are shared globally.
93
93
PyMem_RawFree(VAR)
94
94
95
95
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 ];
96
+ struct xid_types {
97
+ /* Added at runtime by interpreters module. */
98
+ PyTypeObject * SendChannel ;
99
+ PyTypeObject * RecvChannel ;
100
+
101
+ /* heap types */
102
+ PyTypeObject * ChannelID ;
102
103
};
103
104
104
- static int
105
- register_xid_class (PyTypeObject * cls , crossinterpdatafunc shared ,
106
- struct xid_class_registry * classes )
105
+ static void
106
+ clear_xid_types (struct xid_types * types )
107
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 ;
108
+ /* external types */
109
+ if (types -> SendChannel != NULL ) {
110
+ (void )_PyCrossInterpreterData_UnregisterClass (
111
+ types -> SendChannel );
112
+ Py_CLEAR (types -> SendChannel );
113
+ }
114
+ if (types -> RecvChannel != NULL ) {
115
+ (void )_PyCrossInterpreterData_UnregisterClass (
116
+ types -> RecvChannel );
117
+ Py_CLEAR (types -> RecvChannel );
114
118
}
115
- return res ;
116
- }
117
119
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 );
120
+ /* heap types */
121
+ if (types -> ChannelID != NULL ) {
122
+ (void )_PyCrossInterpreterData_UnregisterClass (
123
+ types -> ChannelID );
124
+ Py_CLEAR (types -> ChannelID );
125
125
}
126
126
}
127
127
@@ -223,28 +223,6 @@ add_new_exception(PyObject *mod, const char *name, PyObject *base)
223
223
#define ADD_NEW_EXCEPTION (MOD , NAME , BASE ) \
224
224
add_new_exception(MOD, MODULE_NAME_STR "." Py_STRINGIFY(NAME), BASE)
225
225
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
-
248
226
static int
249
227
wait_for_lock (PyThread_type_lock mutex , PY_TIMEOUT_T timeout )
250
228
{
@@ -269,15 +247,10 @@ wait_for_lock(PyThread_type_lock mutex, PY_TIMEOUT_T timeout)
269
247
/* module state *************************************************************/
270
248
271
249
typedef struct {
272
- struct xid_class_registry xid_classes ;
273
-
274
- /* Added at runtime by interpreters module. */
275
- PyTypeObject * send_channel_type ;
276
- PyTypeObject * recv_channel_type ;
250
+ struct xid_types xid_types ;
277
251
278
252
/* heap types */
279
253
PyTypeObject * ChannelInfoType ;
280
- PyTypeObject * ChannelIDType ;
281
254
282
255
/* exceptions */
283
256
PyObject * ChannelError ;
@@ -315,12 +288,12 @@ static int
315
288
traverse_module_state (module_state * state , visitproc visit , void * arg )
316
289
{
317
290
/* external types */
318
- Py_VISIT (state -> send_channel_type );
319
- Py_VISIT (state -> recv_channel_type );
291
+ Py_VISIT (state -> xid_types . SendChannel );
292
+ Py_VISIT (state -> xid_types . RecvChannel );
320
293
321
294
/* heap types */
322
295
Py_VISIT (state -> ChannelInfoType );
323
- Py_VISIT (state -> ChannelIDType );
296
+ Py_VISIT (state -> xid_types . ChannelID );
324
297
325
298
/* exceptions */
326
299
Py_VISIT (state -> ChannelError );
@@ -335,16 +308,10 @@ traverse_module_state(module_state *state, visitproc visit, void *arg)
335
308
static int
336
309
clear_module_state (module_state * state )
337
310
{
338
- /* external types */
339
- Py_CLEAR (state -> send_channel_type );
340
- Py_CLEAR (state -> recv_channel_type );
311
+ clear_xid_types (& state -> xid_types );
341
312
342
313
/* heap types */
343
314
Py_CLEAR (state -> ChannelInfoType );
344
- if (state -> ChannelIDType != NULL ) {
345
- (void )_PyCrossInterpreterData_UnregisterClass (state -> ChannelIDType );
346
- }
347
- Py_CLEAR (state -> ChannelIDType );
348
315
349
316
/* exceptions */
350
317
Py_CLEAR (state -> ChannelError );
@@ -2210,7 +2177,7 @@ channel_id_converter(PyObject *arg, void *ptr)
2210
2177
struct channel_id_converter_data * data = ptr ;
2211
2178
module_state * state = get_module_state (data -> module );
2212
2179
assert (state != NULL );
2213
- if (PyObject_TypeCheck (arg , state -> ChannelIDType )) {
2180
+ if (PyObject_TypeCheck (arg , state -> xid_types . ChannelID )) {
2214
2181
cid = ((channelid * )arg )-> cid ;
2215
2182
end = ((channelid * )arg )-> end ;
2216
2183
}
@@ -2406,14 +2373,14 @@ channelid_richcompare(PyObject *self, PyObject *other, int op)
2406
2373
goto done ;
2407
2374
}
2408
2375
2409
- if (!PyObject_TypeCheck (self , state -> ChannelIDType )) {
2376
+ if (!PyObject_TypeCheck (self , state -> xid_types . ChannelID )) {
2410
2377
res = Py_NewRef (Py_NotImplemented );
2411
2378
goto done ;
2412
2379
}
2413
2380
2414
2381
channelid * cidobj = (channelid * )self ;
2415
2382
int equal ;
2416
- if (PyObject_TypeCheck (other , state -> ChannelIDType )) {
2383
+ if (PyObject_TypeCheck (other , state -> xid_types . ChannelID )) {
2417
2384
channelid * othercidobj = (channelid * )other ;
2418
2385
equal = (cidobj -> end == othercidobj -> end ) && (cidobj -> cid == othercidobj -> cid );
2419
2386
}
@@ -2494,7 +2461,7 @@ _channelid_from_xid(_PyCrossInterpreterData *data)
2494
2461
2495
2462
// Note that we do not preserve the "resolve" flag.
2496
2463
PyObject * cidobj = NULL ;
2497
- int err = newchannelid (state -> ChannelIDType , xid -> cid , xid -> end ,
2464
+ int err = newchannelid (state -> xid_types . ChannelID , xid -> cid , xid -> end ,
2498
2465
_global_channels (), 0 , 0 ,
2499
2466
(channelid * * )& cidobj );
2500
2467
if (err != 0 ) {
@@ -2614,6 +2581,26 @@ static PyType_Spec channelid_typespec = {
2614
2581
.slots = channelid_typeslots ,
2615
2582
};
2616
2583
2584
+ static PyTypeObject *
2585
+ add_channelid_type (PyObject * mod )
2586
+ {
2587
+ PyTypeObject * cls = (PyTypeObject * )PyType_FromModuleAndSpec (
2588
+ mod , & channelid_typespec , NULL );
2589
+ if (cls == NULL ) {
2590
+ return NULL ;
2591
+ }
2592
+ if (ensure_xid_class (cls , _channelid_shared )) {
2593
+ Py_DECREF (cls );
2594
+ return NULL ;
2595
+ }
2596
+ if (PyModule_AddType (mod , cls ) < 0 ) {
2597
+ (void )_PyCrossInterpreterData_UnregisterClass (cls );
2598
+ Py_DECREF (cls );
2599
+ return NULL ;
2600
+ }
2601
+ return cls ;
2602
+ }
2603
+
2617
2604
2618
2605
/* SendChannel and RecvChannel classes */
2619
2606
@@ -2628,11 +2615,11 @@ _get_current_channelend_type(int end)
2628
2615
}
2629
2616
PyTypeObject * cls ;
2630
2617
if (end == CHANNEL_SEND ) {
2631
- cls = state -> send_channel_type ;
2618
+ cls = state -> xid_types . SendChannel ;
2632
2619
}
2633
2620
else {
2634
2621
assert (end == CHANNEL_RECV );
2635
- cls = state -> recv_channel_type ;
2622
+ cls = state -> xid_types . RecvChannel ;
2636
2623
}
2637
2624
if (cls == NULL ) {
2638
2625
// Force the module to be loaded, to register the type.
@@ -2646,10 +2633,10 @@ _get_current_channelend_type(int end)
2646
2633
}
2647
2634
Py_DECREF (highlevel );
2648
2635
if (end == CHANNEL_SEND ) {
2649
- cls = state -> send_channel_type ;
2636
+ cls = state -> xid_types . SendChannel ;
2650
2637
}
2651
2638
else {
2652
- cls = state -> recv_channel_type ;
2639
+ cls = state -> xid_types . RecvChannel ;
2653
2640
}
2654
2641
assert (cls != NULL );
2655
2642
}
@@ -2697,23 +2684,30 @@ set_channelend_types(PyObject *mod, PyTypeObject *send, PyTypeObject *recv)
2697
2684
if (state == NULL ) {
2698
2685
return -1 ;
2699
2686
}
2700
- struct xid_class_registry * xid_classes = & state -> xid_classes ;
2687
+ struct xid_types * types = & state -> xid_types ;
2701
2688
2702
- if (state -> send_channel_type != NULL
2703
- || state -> recv_channel_type != NULL )
2704
- {
2705
- PyErr_SetString (PyExc_TypeError , "already registered" );
2706
- return -1 ;
2689
+ // Clear the old values if the .py module was reloaded.
2690
+ if (types -> SendChannel != NULL ) {
2691
+ (void )_PyCrossInterpreterData_UnregisterClass (
2692
+ types -> SendChannel );
2693
+ Py_CLEAR (types -> SendChannel );
2694
+ }
2695
+ if (types -> RecvChannel != NULL ) {
2696
+ (void )_PyCrossInterpreterData_UnregisterClass (
2697
+ types -> RecvChannel );
2698
+ Py_CLEAR (types -> RecvChannel );
2707
2699
}
2708
- state -> send_channel_type = (PyTypeObject * )Py_NewRef (send );
2709
- state -> recv_channel_type = (PyTypeObject * )Py_NewRef (recv );
2710
2700
2711
- if (register_xid_class (send , _channelend_shared , xid_classes )) {
2701
+ // Add and register the new types.
2702
+ if (ensure_xid_class (send , _channelend_shared ) < 0 ) {
2712
2703
return -1 ;
2713
2704
}
2714
- if (register_xid_class (recv , _channelend_shared , xid_classes )) {
2705
+ if (ensure_xid_class (recv , _channelend_shared ) < 0 ) {
2706
+ (void )_PyCrossInterpreterData_UnregisterClass (send );
2715
2707
return -1 ;
2716
2708
}
2709
+ types -> SendChannel = (PyTypeObject * )Py_NewRef (send );
2710
+ types -> RecvChannel = (PyTypeObject * )Py_NewRef (recv );
2717
2711
2718
2712
return 0 ;
2719
2713
}
@@ -2792,7 +2786,7 @@ channelsmod_create(PyObject *self, PyObject *Py_UNUSED(ignored))
2792
2786
return NULL ;
2793
2787
}
2794
2788
PyObject * cidobj = NULL ;
2795
- int err = newchannelid (state -> ChannelIDType , cid , 0 ,
2789
+ int err = newchannelid (state -> xid_types . ChannelID , cid , 0 ,
2796
2790
& _globals .channels , 0 , 0 ,
2797
2791
(channelid * * )& cidobj );
2798
2792
if (handle_channel_error (err , self , cid )) {
@@ -2864,7 +2858,7 @@ channelsmod_list_all(PyObject *self, PyObject *Py_UNUSED(ignored))
2864
2858
int64_t * cur = cids ;
2865
2859
for (int64_t i = 0 ; i < count ; cur ++ , i ++ ) {
2866
2860
PyObject * cidobj = NULL ;
2867
- int err = newchannelid (state -> ChannelIDType , * cur , 0 ,
2861
+ int err = newchannelid (state -> xid_types . ChannelID , * cur , 0 ,
2868
2862
& _globals .channels , 0 , 0 ,
2869
2863
(channelid * * )& cidobj );
2870
2864
if (handle_channel_error (err , self , * cur )) {
@@ -3214,7 +3208,7 @@ channelsmod__channel_id(PyObject *self, PyObject *args, PyObject *kwds)
3214
3208
if (state == NULL ) {
3215
3209
return NULL ;
3216
3210
}
3217
- PyTypeObject * cls = state -> ChannelIDType ;
3211
+ PyTypeObject * cls = state -> xid_types . ChannelID ;
3218
3212
3219
3213
PyObject * mod = get_module_from_owned_type (cls );
3220
3214
assert (mod == self );
@@ -3294,13 +3288,13 @@ module_exec(PyObject *mod)
3294
3288
if (_globals_init () != 0 ) {
3295
3289
return -1 ;
3296
3290
}
3297
- struct xid_class_registry * xid_classes = NULL ;
3291
+ struct xid_types * xid_types = NULL ;
3298
3292
3299
3293
module_state * state = get_module_state (mod );
3300
3294
if (state == NULL ) {
3301
3295
goto error ;
3302
3296
}
3303
- xid_classes = & state -> xid_classes ;
3297
+ xid_types = & state -> xid_types ;
3304
3298
3305
3299
/* Add exception types */
3306
3300
if (exceptions_init (mod ) != 0 ) {
@@ -3319,9 +3313,8 @@ module_exec(PyObject *mod)
3319
3313
}
3320
3314
3321
3315
// ChannelID
3322
- state -> ChannelIDType = add_new_type (
3323
- mod , & channelid_typespec , _channelid_shared , xid_classes );
3324
- if (state -> ChannelIDType == NULL ) {
3316
+ xid_types -> ChannelID = add_channelid_type (mod );
3317
+ if (xid_types -> ChannelID == NULL ) {
3325
3318
goto error ;
3326
3319
}
3327
3320
@@ -3332,8 +3325,8 @@ module_exec(PyObject *mod)
3332
3325
return 0 ;
3333
3326
3334
3327
error :
3335
- if (xid_classes != NULL ) {
3336
- clear_xid_class_registry ( xid_classes );
3328
+ if (xid_types != NULL ) {
3329
+ clear_xid_types ( xid_types );
3337
3330
}
3338
3331
_globals_fini ();
3339
3332
return -1 ;
@@ -3360,9 +3353,6 @@ module_clear(PyObject *mod)
3360
3353
module_state * state = get_module_state (mod );
3361
3354
assert (state != NULL );
3362
3355
3363
- // Before clearing anything, we unregister the various XID types. */
3364
- clear_xid_class_registry (& state -> xid_classes );
3365
-
3366
3356
// Now we clear the module state.
3367
3357
clear_module_state (state );
3368
3358
return 0 ;
@@ -3374,9 +3364,6 @@ module_free(void *mod)
3374
3364
module_state * state = get_module_state (mod );
3375
3365
assert (state != NULL );
3376
3366
3377
- // Before clearing anything, we unregister the various XID types. */
3378
- clear_xid_class_registry (& state -> xid_classes );
3379
-
3380
3367
// Now we clear the module state.
3381
3368
clear_module_state (state );
3382
3369
0 commit comments