| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 332cd5e commit 7f8bfc9
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -65,6 +65,79 @@ PyAPI_FUNC(_PyInitError) _PyPathConfig_Calculate( | |||
| 65 | 65 | PyAPI_FUNC(void) _PyPathConfig_Clear(_PyPathConfig *config); | |
| 66 | 66 | ||
| 67 | 67 | ||
| 68 | + /* interpreter state */ | ||
| 69 | + | ||
| 70 | + PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpID(PY_INT64_T); | ||
| 71 | + | ||
| 72 | + | ||
| 73 | + /* cross-interpreter data */ | ||
| 74 | + | ||
| 75 | + struct _xid; | ||
| 76 | + | ||
| 77 | + // _PyCrossInterpreterData is similar to Py_buffer as an effectively | ||
| 78 | + // opaque struct that holds data outside the object machinery. This | ||
| 79 | + // is necessary to pass between interpreters in the same process. | ||
| 80 | + typedef struct _xid { | ||
| 81 | + // data is the cross-interpreter-safe derivation of a Python object | ||
| 82 | + // (see _PyObject_GetCrossInterpreterData). It will be NULL if the | ||
| 83 | + // new_object func (below) encodes the data. | ||
| 84 | + void *data; | ||
| 85 | + // obj is the Python object from which the data was derived. This | ||
| 86 | + // is non-NULL only if the data remains bound to the object in some | ||
| 87 | + // way, such that the object must be "released" (via a decref) when | ||
| 88 | + // the data is released. In that case it is automatically | ||
| 89 | + // incref'ed (to match the automatic decref when releaed). | ||
| 90 | + PyObject *obj; | ||
| 91 | + // interp is the ID of the owning interpreter of the original | ||
| 92 | + // object. It corresponds to the active interpreter when | ||
| 93 | + // _PyObject_GetCrossInterpreterData() was called. This should only | ||
| 94 | + // be set by the cross-interpreter machinery. | ||
| 95 | + // | ||
| 96 | + // We use the ID rather than the PyInterpreterState to avoid issues | ||
| 97 | + // with deleted interpreters. | ||
| 98 | + int64_t interp; | ||
| 99 | + // new_object is a function that returns a new object in the current | ||
| 100 | + // interpreter given the data. The resulting object (a new | ||
| 101 | + // reference) will be equivalent to the original object. This field | ||
| 102 | + // is required. | ||
| 103 | + PyObject *(*new_object)(struct _xid *); | ||
| 104 | + // free is called when the data is released. If it is NULL then | ||
| 105 | + // nothing will be done to free the data. For some types this is | ||
| 106 | + // okay (e.g. bytes) and for those types this field should be set | ||
| 107 | + // to NULL. However, for most the data was allocated just for | ||
| 108 | + // cross-interpreter use, so it must be freed when | ||
| 109 | + // _PyCrossInterpreterData_Release is called or the memory will | ||
| 110 | + // leak. In that case, at the very least this field should be set | ||
| 111 | + // to PyMem_RawFree (the default if not explicitly set to NULL). | ||
| 112 | + // The call will happen with the original interpreter activated. | ||
| 113 | + void (*free)(void *); | ||
| 114 | + } _PyCrossInterpreterData; | ||
| 115 | + | ||
| 116 | + typedef int (*crossinterpdatafunc)(PyObject *, _PyCrossInterpreterData *); | ||
| 117 | + PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *); | ||
| 118 | + | ||
| 119 | + PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *); | ||
| 120 | + PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *); | ||
| 121 | + PyAPI_FUNC(void) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *); | ||
| 122 | + | ||
| 123 | + /* cross-interpreter data registry */ | ||
| 124 | + | ||
| 125 | + /* For now we use a global registry of shareable classes. An | ||
| 126 | + alternative would be to add a tp_* slot for a class's | ||
| 127 | + crossinterpdatafunc. It would be simpler and more efficient. */ | ||
| 128 | + | ||
| 129 | + PyAPI_FUNC(int) _PyCrossInterpreterData_Register_Class(PyTypeObject *, crossinterpdatafunc); | ||
| 130 | + PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *); | ||
| 131 | + | ||
| 132 | + struct _xidregitem; | ||
| 133 | + | ||
| 134 | + struct _xidregitem { | ||
| 135 | + PyTypeObject *cls; | ||
| 136 | + crossinterpdatafunc getdata; | ||
| 137 | + struct _xidregitem *next; | ||
| 138 | + }; | ||
| 139 | + | ||
| 140 | + | ||
| 68 | 141 | /* Full Python runtime state */ | |
| 69 | 142 | ||
| 70 | 143 | typedef struct pyruntimestate { | |
@@ -86,6 +159,11 @@ typedef struct pyruntimestate { | |||
| 86 | 159 | using a Python int. */ | |
| 87 | 160 | int64_t next_id; | |
| 88 | 161 | } interpreters; | |
| 162 | + // XXX Remove this field once we have a tp_* slot. | ||
| 163 | + struct _xidregistry { | ||
| 164 | + PyThread_type_lock mutex; | ||
| 165 | + struct _xidregitem *head; | ||
| 166 | + } xidregistry; | ||
| 89 | 167 | ||
| 90 | 168 | #define NEXITFUNCS 32 | |
| 91 | 169 | void (*exitfuncs[NEXITFUNCS])(void); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments