@@ -30,9 +30,13 @@ typedef struct {
3030 (_PyMainInterpreterConfig){.install_signal_handlers = -1}
3131/* Note: _PyMainInterpreterConfig_INIT sets other fields to 0/NULL */
3232
33+ PyAPI_FUNC (int ) _PyInterpreterState_RequiresIDRef (PyInterpreterState * );
34+ PyAPI_FUNC (void ) _PyInterpreterState_RequireIDRef (PyInterpreterState * , int );
35+
3336PyAPI_FUNC (_PyCoreConfig * ) _PyInterpreterState_GetCoreConfig (PyInterpreterState * );
3437PyAPI_FUNC (_PyMainInterpreterConfig * ) _PyInterpreterState_GetMainConfig (PyInterpreterState * );
3538
39+ PyAPI_FUNC (PyObject * ) _PyInterpreterState_GetMainModule (PyInterpreterState * );
3640
3741/* State unique per thread */
3842
@@ -214,6 +218,65 @@ PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *);
214218
215219typedef struct _frame * (* PyThreadFrameGetter )(PyThreadState * self_ );
216220
221+ /* cross-interpreter data */
222+
223+ struct _xid ;
224+
225+ // _PyCrossInterpreterData is similar to Py_buffer as an effectively
226+ // opaque struct that holds data outside the object machinery. This
227+ // is necessary to pass safely between interpreters in the same process.
228+ typedef struct _xid {
229+ // data is the cross-interpreter-safe derivation of a Python object
230+ // (see _PyObject_GetCrossInterpreterData). It will be NULL if the
231+ // new_object func (below) encodes the data.
232+ void * data ;
233+ // obj is the Python object from which the data was derived. This
234+ // is non-NULL only if the data remains bound to the object in some
235+ // way, such that the object must be "released" (via a decref) when
236+ // the data is released. In that case the code that sets the field,
237+ // likely a registered "crossinterpdatafunc", is responsible for
238+ // ensuring it owns the reference (i.e. incref).
239+ PyObject * obj ;
240+ // interp is the ID of the owning interpreter of the original
241+ // object. It corresponds to the active interpreter when
242+ // _PyObject_GetCrossInterpreterData() was called. This should only
243+ // be set by the cross-interpreter machinery.
244+ //
245+ // We use the ID rather than the PyInterpreterState to avoid issues
246+ // with deleted interpreters. Note that IDs are never re-used, so
247+ // each one will always correspond to a specific interpreter
248+ // (whether still alive or not).
249+ int64_t interp ;
250+ // new_object is a function that returns a new object in the current
251+ // interpreter given the data. The resulting object (a new
252+ // reference) will be equivalent to the original object. This field
253+ // is required.
254+ PyObject * (* new_object )(struct _xid * );
255+ // free is called when the data is released. If it is NULL then
256+ // nothing will be done to free the data. For some types this is
257+ // okay (e.g. bytes) and for those types this field should be set
258+ // to NULL. However, for most the data was allocated just for
259+ // cross-interpreter use, so it must be freed when
260+ // _PyCrossInterpreterData_Release is called or the memory will
261+ // leak. In that case, at the very least this field should be set
262+ // to PyMem_RawFree (the default if not explicitly set to NULL).
263+ // The call will happen with the original interpreter activated.
264+ void (* free )(void * );
265+ } _PyCrossInterpreterData ;
266+
267+ PyAPI_FUNC (int ) _PyObject_GetCrossInterpreterData (PyObject * , _PyCrossInterpreterData * );
268+ PyAPI_FUNC (PyObject * ) _PyCrossInterpreterData_NewObject (_PyCrossInterpreterData * );
269+ PyAPI_FUNC (void ) _PyCrossInterpreterData_Release (_PyCrossInterpreterData * );
270+
271+ PyAPI_FUNC (int ) _PyObject_CheckCrossInterpreterData (PyObject * );
272+
273+ /* cross-interpreter data registry */
274+
275+ typedef int (* crossinterpdatafunc )(PyObject * , struct _xid * );
276+
277+ PyAPI_FUNC (int ) _PyCrossInterpreterData_RegisterClass (PyTypeObject * , crossinterpdatafunc );
278+ PyAPI_FUNC (crossinterpdatafunc ) _PyCrossInterpreterData_Lookup (PyObject * );
279+
217280#ifdef __cplusplus
218281}
219282#endif
0 commit comments