@@ -38,28 +38,28 @@ extern int _Py_CallInInterpreterAndRawFree(
38
38
/* cross-interpreter data */
39
39
/**************************/
40
40
41
- typedef struct _xid _PyCrossInterpreterData ;
42
- typedef PyObject * (* xid_newobjectfunc )(_PyCrossInterpreterData * );
41
+ typedef struct _xid _PyXIData_t ;
42
+ typedef PyObject * (* xid_newobjectfunc )(_PyXIData_t * );
43
43
typedef void (* xid_freefunc )(void * );
44
44
45
- // _PyCrossInterpreterData is similar to Py_buffer as an effectively
45
+ // _PyXIData_t is similar to Py_buffer as an effectively
46
46
// opaque struct that holds data outside the object machinery. This
47
47
// is necessary to pass safely between interpreters in the same process.
48
48
struct _xid {
49
49
// data is the cross-interpreter-safe derivation of a Python object
50
- // (see _PyObject_GetCrossInterpreterData ). It will be NULL if the
50
+ // (see _PyObject_GetXIData ). It will be NULL if the
51
51
// new_object func (below) encodes the data.
52
52
void * data ;
53
53
// obj is the Python object from which the data was derived. This
54
54
// is non-NULL only if the data remains bound to the object in some
55
55
// way, such that the object must be "released" (via a decref) when
56
56
// the data is released. In that case the code that sets the field,
57
- // likely a registered "crossinterpdatafunc ", is responsible for
57
+ // likely a registered "xidatafunc ", is responsible for
58
58
// ensuring it owns the reference (i.e. incref).
59
59
PyObject * obj ;
60
60
// interp is the ID of the owning interpreter of the original
61
61
// object. It corresponds to the active interpreter when
62
- // _PyObject_GetCrossInterpreterData () was called. This should only
62
+ // _PyObject_GetXIData () was called. This should only
63
63
// be set by the cross-interpreter machinery.
64
64
//
65
65
// We use the ID rather than the PyInterpreterState to avoid issues
@@ -77,96 +77,77 @@ struct _xid {
77
77
// okay (e.g. bytes) and for those types this field should be set
78
78
// to NULL. However, for most the data was allocated just for
79
79
// cross-interpreter use, so it must be freed when
80
- // _PyCrossInterpreterData_Release is called or the memory will
80
+ // _PyXIData_Release is called or the memory will
81
81
// leak. In that case, at the very least this field should be set
82
82
// to PyMem_RawFree (the default if not explicitly set to NULL).
83
83
// The call will happen with the original interpreter activated.
84
84
xid_freefunc free ;
85
85
};
86
86
87
- PyAPI_FUNC (_PyCrossInterpreterData * ) _PyCrossInterpreterData_New (void );
88
- PyAPI_FUNC (void ) _PyCrossInterpreterData_Free ( _PyCrossInterpreterData * data );
87
+ PyAPI_FUNC (_PyXIData_t * ) _PyXIData_New (void );
88
+ PyAPI_FUNC (void ) _PyXIData_Free ( _PyXIData_t * data );
89
89
90
- #define _PyCrossInterpreterData_DATA (DATA ) ((DATA)->data)
91
- #define _PyCrossInterpreterData_OBJ (DATA ) ((DATA)->obj)
92
- #define _PyCrossInterpreterData_INTERPID (DATA ) ((DATA)->interpid)
90
+ #define _PyXIData_DATA (DATA ) ((DATA)->data)
91
+ #define _PyXIData_OBJ (DATA ) ((DATA)->obj)
92
+ #define _PyXIData_INTERPID (DATA ) ((DATA)->interpid)
93
93
// Users should not need getters for "new_object" or "free".
94
94
95
95
96
+ /* getting cross-interpreter data */
97
+
98
+ typedef int (* xidatafunc )(PyThreadState * tstate , PyObject * , _PyXIData_t * );
99
+
100
+ typedef struct _xid_lookup_state _PyXIData_lookup_t ;
101
+
102
+ PyAPI_FUNC (xidatafunc ) _PyXIData_Lookup (PyObject * );
103
+ PyAPI_FUNC (int ) _PyObject_CheckXIData (PyObject * );
104
+ PyAPI_FUNC (int ) _PyObject_GetXIData (PyObject * , _PyXIData_t * );
105
+
106
+
107
+ /* using cross-interpreter data */
108
+
109
+ PyAPI_FUNC (PyObject * ) _PyXIData_NewObject (_PyXIData_t * );
110
+ PyAPI_FUNC (int ) _PyXIData_Release (_PyXIData_t * );
111
+ PyAPI_FUNC (int ) _PyXIData_ReleaseAndRawFree (_PyXIData_t * );
112
+
113
+
96
114
/* defining cross-interpreter data */
97
115
98
- PyAPI_FUNC (void ) _PyCrossInterpreterData_Init (
99
- _PyCrossInterpreterData * data ,
116
+ PyAPI_FUNC (void ) _PyXIData_Init (
117
+ _PyXIData_t * data ,
100
118
PyInterpreterState * interp , void * shared , PyObject * obj ,
101
119
xid_newobjectfunc new_object );
102
- PyAPI_FUNC (int ) _PyCrossInterpreterData_InitWithSize (
103
- _PyCrossInterpreterData * ,
120
+ PyAPI_FUNC (int ) _PyXIData_InitWithSize (
121
+ _PyXIData_t * ,
104
122
PyInterpreterState * interp , const size_t , PyObject * ,
105
123
xid_newobjectfunc );
106
- PyAPI_FUNC (void ) _PyCrossInterpreterData_Clear (
107
- PyInterpreterState * , _PyCrossInterpreterData * );
124
+ PyAPI_FUNC (void ) _PyXIData_Clear ( PyInterpreterState * , _PyXIData_t * );
108
125
109
126
// Normally the Init* functions are sufficient. The only time
110
127
// additional initialization might be needed is to set the "free" func,
111
128
// though that should be infrequent.
112
- #define _PyCrossInterpreterData_SET_FREE (DATA , FUNC ) \
129
+ #define _PyXIData_SET_FREE (DATA , FUNC ) \
113
130
do { \
114
131
(DATA)->free = (FUNC); \
115
132
} while (0)
116
133
// Additionally, some shareable types are essentially light wrappers
117
- // around other shareable types. The crossinterpdatafunc of the wrapper
134
+ // around other shareable types. The xidatafunc of the wrapper
118
135
// can often be implemented by calling the wrapped object's
119
- // crossinterpdatafunc and then changing the "new_object" function.
120
- // We have _PyCrossInterpreterData_SET_NEW_OBJECT () here for that,
136
+ // xidatafunc and then changing the "new_object" function.
137
+ // We have _PyXIData_SET_NEW_OBJECT () here for that,
121
138
// but might be better to have a function like
122
- // _PyCrossInterpreterData_AdaptToWrapper () instead.
123
- #define _PyCrossInterpreterData_SET_NEW_OBJECT (DATA , FUNC ) \
139
+ // _PyXIData_AdaptToWrapper () instead.
140
+ #define _PyXIData_SET_NEW_OBJECT (DATA , FUNC ) \
124
141
do { \
125
142
(DATA)->new_object = (FUNC); \
126
143
} while (0)
127
144
128
145
129
- /* using cross-interpreter data */
130
-
131
- PyAPI_FUNC (int ) _PyObject_CheckCrossInterpreterData (PyObject * );
132
- PyAPI_FUNC (int ) _PyObject_GetCrossInterpreterData (PyObject * , _PyCrossInterpreterData * );
133
- PyAPI_FUNC (PyObject * ) _PyCrossInterpreterData_NewObject (_PyCrossInterpreterData * );
134
- PyAPI_FUNC (int ) _PyCrossInterpreterData_Release (_PyCrossInterpreterData * );
135
- PyAPI_FUNC (int ) _PyCrossInterpreterData_ReleaseAndRawFree (_PyCrossInterpreterData * );
136
-
137
-
138
146
/* cross-interpreter data registry */
139
147
140
- // For now we use a global registry of shareable classes. An
141
- // alternative would be to add a tp_* slot for a class's
142
- // crossinterpdatafunc. It would be simpler and more efficient.
143
-
144
- typedef int (* crossinterpdatafunc )(PyThreadState * tstate , PyObject * ,
145
- _PyCrossInterpreterData * );
146
-
147
- struct _xidregitem ;
148
-
149
- struct _xidregitem {
150
- struct _xidregitem * prev ;
151
- struct _xidregitem * next ;
152
- /* This can be a dangling pointer, but only if weakref is set. */
153
- PyTypeObject * cls ;
154
- /* This is NULL for builtin types. */
155
- PyObject * weakref ;
156
- size_t refcount ;
157
- crossinterpdatafunc getdata ;
158
- };
159
-
160
- struct _xidregistry {
161
- int global ; /* builtin types or heap types */
162
- int initialized ;
163
- PyMutex mutex ;
164
- struct _xidregitem * head ;
165
- };
166
-
167
- PyAPI_FUNC (int ) _PyCrossInterpreterData_RegisterClass (PyTypeObject * , crossinterpdatafunc );
168
- PyAPI_FUNC (int ) _PyCrossInterpreterData_UnregisterClass (PyTypeObject * );
169
- PyAPI_FUNC (crossinterpdatafunc ) _PyCrossInterpreterData_Lookup (PyObject * );
148
+ #define Py_CORE_CROSSINTERP_DATA_REGISTRY_H
149
+ #include "pycore_crossinterp_data_registry.h"
150
+ #undef Py_CORE_CROSSINTERP_DATA_REGISTRY_H
170
151
171
152
172
153
/*****************************/
@@ -175,22 +156,19 @@ PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *);
175
156
176
157
struct _xi_runtime_state {
177
158
// builtin types
178
- // XXX Remove this field once we have a tp_* slot.
179
- struct _xidregistry registry ;
159
+ _PyXIData_lookup_t data_lookup ;
180
160
};
181
161
182
162
struct _xi_state {
183
163
// heap types
184
- // XXX Remove this field once we have a tp_* slot.
185
- struct _xidregistry registry ;
164
+ _PyXIData_lookup_t data_lookup ;
186
165
187
166
// heap types
188
167
PyObject * PyExc_NotShareableError ;
189
168
};
190
169
191
170
extern PyStatus _PyXI_Init (PyInterpreterState * interp );
192
171
extern void _PyXI_Fini (PyInterpreterState * interp );
193
-
194
172
extern PyStatus _PyXI_InitTypes (PyInterpreterState * interp );
195
173
extern void _PyXI_FiniTypes (PyInterpreterState * interp );
196
174
0 commit comments