1 #ifndef Py_INTERNAL_CROSSINTERP_H 2 #define Py_INTERNAL_CROSSINTERP_H 3 #ifdef __cplusplus 4 extern "C" { 5 #endif 6 7 #ifndef Py_BUILD_CORE 8 # error "this header requires Py_BUILD_CORE define" 9 #endif 10 11 #include "pycore_lock.h" // PyMutex 12 #include "pycore_pyerrors.h" 13 14 /**************/ 15 /* exceptions */ 16 /**************/ 17 18 PyAPI_DATA(PyObject *) PyExc_InterpreterError; 19 PyAPI_DATA(PyObject *) PyExc_InterpreterNotFoundError; 20 21 22 /***************************/ 23 /* cross-interpreter calls */ 24 /***************************/ 25 26 typedef int (*_Py_simple_func)(void *); 27 extern int _Py_CallInInterpreter( 28 PyInterpreterState *interp, 29 _Py_simple_func func, 30 void *arg); 31 extern int _Py_CallInInterpreterAndRawFree( 32 PyInterpreterState *interp, 33 _Py_simple_func func, 34 void *arg); 35 36 37 /**************************/ 38 /* cross-interpreter data */ 39 /**************************/ 40 41 typedef struct _xid _PyCrossInterpreterData; 42 typedef PyObject *(*xid_newobjectfunc)(_PyCrossInterpreterData *); 43 typedef void (*xid_freefunc)(void *); 44 45 // _PyCrossInterpreterData is similar to Py_buffer as an effectively 46 // opaque struct that holds data outside the object machinery. This 47 // is necessary to pass safely between interpreters in the same process. 48 struct _xid { 49 // data is the cross-interpreter-safe derivation of a Python object 50 // (see _PyObject_GetCrossInterpreterData). It will be NULL if the 51 // new_object func (below) encodes the data. 52 void *data; 53 // obj is the Python object from which the data was derived. This 54 // is non-NULL only if the data remains bound to the object in some 55 // way, such that the object must be "released" (via a decref) when 56 // the data is released. In that case the code that sets the field, 57 // likely a registered "crossinterpdatafunc", is responsible for 58 // ensuring it owns the reference (i.e. incref). 59 PyObject *obj; 60 // interp is the ID of the owning interpreter of the original 61 // object. It corresponds to the active interpreter when 62 // _PyObject_GetCrossInterpreterData() was called. This should only 63 // be set by the cross-interpreter machinery. 64 // 65 // We use the ID rather than the PyInterpreterState to avoid issues 66 // with deleted interpreters. Note that IDs are never re-used, so 67 // each one will always correspond to a specific interpreter 68 // (whether still alive or not). 69 int64_t interpid; 70 // new_object is a function that returns a new object in the current 71 // interpreter given the data. The resulting object (a new 72 // reference) will be equivalent to the original object. This field 73 // is required. 74 xid_newobjectfunc new_object; 75 // free is called when the data is released. If it is NULL then 76 // nothing will be done to free the data. For some types this is 77 // okay (e.g. bytes) and for those types this field should be set 78 // to NULL. However, for most the data was allocated just for 79 // cross-interpreter use, so it must be freed when 80 // _PyCrossInterpreterData_Release is called or the memory will 81 // leak. In that case, at the very least this field should be set 82 // to PyMem_RawFree (the default if not explicitly set to NULL). 83 // The call will happen with the original interpreter activated. 84 xid_freefunc free; 85 }; 86 87 PyAPI_FUNC(_PyCrossInterpreterData *) _PyCrossInterpreterData_New(void); 88 PyAPI_FUNC(void) _PyCrossInterpreterData_Free(_PyCrossInterpreterData *data); 89 90 #define _PyCrossInterpreterData_DATA(DATA) ((DATA)->data) 91 #define _PyCrossInterpreterData_OBJ(DATA) ((DATA)->obj) 92 #define _PyCrossInterpreterData_INTERPID(DATA) ((DATA)->interpid) 93 // Users should not need getters for "new_object" or "free". 94 95 96 /* defining cross-interpreter data */ 97 98 PyAPI_FUNC(void) _PyCrossInterpreterData_Init( 99 _PyCrossInterpreterData *data, 100 PyInterpreterState *interp, void *shared, PyObject *obj, 101 xid_newobjectfunc new_object); 102 PyAPI_FUNC(int) _PyCrossInterpreterData_InitWithSize( 103 _PyCrossInterpreterData *, 104 PyInterpreterState *interp, const size_t, PyObject *, 105 xid_newobjectfunc); 106 PyAPI_FUNC(void) _PyCrossInterpreterData_Clear( 107 PyInterpreterState *, _PyCrossInterpreterData *); 108 109 // Normally the Init* functions are sufficient. The only time 110 // additional initialization might be needed is to set the "free" func, 111 // though that should be infrequent. 112 #define _PyCrossInterpreterData_SET_FREE(DATA, FUNC) \ 113 do { \ 114 (DATA)->free = (FUNC); \ 115 } while (0) 116 // Additionally, some shareable types are essentially light wrappers 117 // around other shareable types. The crossinterpdatafunc of the wrapper 118 // 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, 121 // but might be better to have a function like 122 // _PyCrossInterpreterData_AdaptToWrapper() instead. 123 #define _PyCrossInterpreterData_SET_NEW_OBJECT(DATA, FUNC) \ 124 do { \ 125 (DATA)->new_object = (FUNC); \ 126 } while (0) 127 128 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 /* cross-interpreter data registry */ 139 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 *); 170 171 172 /*****************************/ 173 /* runtime state & lifecycle */ 174 /*****************************/ 175 176 struct _xi_runtime_state { 177 // builtin types 178 // XXX Remove this field once we have a tp_* slot. 179 struct _xidregistry registry; 180 }; 181 182 struct _xi_state { 183 // heap types 184 // XXX Remove this field once we have a tp_* slot. 185 struct _xidregistry registry; 186 187 // heap types 188 PyObject *PyExc_NotShareableError; 189 }; 190 191 extern PyStatus _PyXI_Init(PyInterpreterState *interp); 192 extern void _PyXI_Fini(PyInterpreterState *interp); 193 194 extern PyStatus _PyXI_InitTypes(PyInterpreterState *interp); 195 extern void _PyXI_FiniTypes(PyInterpreterState *interp); 196 197 #define _PyInterpreterState_GetXIState(interp) (&(interp)->xi) 198 199 200 /***************************/ 201 /* short-term data sharing */ 202 /***************************/ 203 204 // Ultimately we'd like to preserve enough information about the 205 // exception and traceback that we could re-constitute (or at least 206 // simulate, a la traceback.TracebackException), and even chain, a copy 207 // of the exception in the calling interpreter. 208 209 typedef struct _excinfo { 210 struct _excinfo_type { 211 PyTypeObject *builtin; 212 const char *name; 213 const char *qualname; 214 const char *module; 215 } type; 216 const char *msg; 217 const char *errdisplay; 218 } _PyXI_excinfo; 219 220 PyAPI_FUNC(int) _PyXI_InitExcInfo(_PyXI_excinfo *info, PyObject *exc); 221 PyAPI_FUNC(PyObject *) _PyXI_FormatExcInfo(_PyXI_excinfo *info); 222 PyAPI_FUNC(PyObject *) _PyXI_ExcInfoAsObject(_PyXI_excinfo *info); 223 PyAPI_FUNC(void) _PyXI_ClearExcInfo(_PyXI_excinfo *info); 224 225 226 typedef enum error_code { 227 _PyXI_ERR_NO_ERROR = 0, 228 _PyXI_ERR_UNCAUGHT_EXCEPTION = -1, 229 _PyXI_ERR_OTHER = -2, 230 _PyXI_ERR_NO_MEMORY = -3, 231 _PyXI_ERR_ALREADY_RUNNING = -4, 232 _PyXI_ERR_MAIN_NS_FAILURE = -5, 233 _PyXI_ERR_APPLY_NS_FAILURE = -6, 234 _PyXI_ERR_NOT_SHAREABLE = -7, 235 } _PyXI_errcode; 236 237 238 typedef struct _sharedexception { 239 // The originating interpreter. 240 PyInterpreterState *interp; 241 // The kind of error to propagate. 242 _PyXI_errcode code; 243 // The exception information to propagate, if applicable. 244 // This is populated only for some error codes, 245 // but always for _PyXI_ERR_UNCAUGHT_EXCEPTION. 246 _PyXI_excinfo uncaught; 247 } _PyXI_error; 248 249 PyAPI_FUNC(PyObject *) _PyXI_ApplyError(_PyXI_error *err); 250 251 252 typedef struct xi_session _PyXI_session; 253 typedef struct _sharedns _PyXI_namespace; 254 255 PyAPI_FUNC(void) _PyXI_FreeNamespace(_PyXI_namespace *ns); 256 PyAPI_FUNC(_PyXI_namespace *) _PyXI_NamespaceFromNames(PyObject *names); 257 PyAPI_FUNC(int) _PyXI_FillNamespaceFromDict( 258 _PyXI_namespace *ns, 259 PyObject *nsobj, 260 _PyXI_session *session); 261 PyAPI_FUNC(int) _PyXI_ApplyNamespace( 262 _PyXI_namespace *ns, 263 PyObject *nsobj, 264 PyObject *dflt); 265 266 267 // A cross-interpreter session involves entering an interpreter 268 // (_PyXI_Enter()), doing some work with it, and finally exiting 269 // that interpreter (_PyXI_Exit()). 270 // 271 // At the boundaries of the session, both entering and exiting, 272 // data may be exchanged between the previous interpreter and the 273 // target one in a thread-safe way that does not violate the 274 // isolation between interpreters. This includes setting objects 275 // in the target's __main__ module on the way in, and capturing 276 // uncaught exceptions on the way out. 277 struct xi_session { 278 // Once a session has been entered, this is the tstate that was 279 // current before the session. If it is different from cur_tstate 280 // then we must have switched interpreters. Either way, this will 281 // be the current tstate once we exit the session. 282 PyThreadState *prev_tstate; 283 // Once a session has been entered, this is the current tstate. 284 // It must be current when the session exits. 285 PyThreadState *init_tstate; 286 // This is true if init_tstate needs cleanup during exit. 287 int own_init_tstate; 288 289 // This is true if, while entering the session, init_thread took 290 // "ownership" of the interpreter's __main__ module. This means 291 // it is the only thread that is allowed to run code there. 292 // (Caveat: for now, users may still run exec() against the 293 // __main__ module's dict, though that isn't advisable.) 294 int running; 295 // This is a cached reference to the __dict__ of the entered 296 // interpreter's __main__ module. It is looked up when at the 297 // beginning of the session as a convenience. 298 PyObject *main_ns; 299 300 // This is set if the interpreter is entered and raised an exception 301 // that needs to be handled in some special way during exit. 302 _PyXI_errcode *error_override; 303 // This is set if exit captured an exception to propagate. 304 _PyXI_error *error; 305 306 // -- pre-allocated memory -- 307 _PyXI_error _error; 308 _PyXI_errcode _error_override; 309 }; 310 311 PyAPI_FUNC(int) _PyXI_Enter( 312 _PyXI_session *session, 313 PyInterpreterState *interp, 314 PyObject *nsupdates); 315 PyAPI_FUNC(void) _PyXI_Exit(_PyXI_session *session); 316 317 PyAPI_FUNC(PyObject *) _PyXI_ApplyCapturedException(_PyXI_session *session); 318 PyAPI_FUNC(int) _PyXI_HasCapturedException(_PyXI_session *session); 319 320 321 /*************/ 322 /* other API */ 323 /*************/ 324 325 // Export for _testinternalcapi shared extension 326 PyAPI_FUNC(PyInterpreterState *) _PyXI_NewInterpreter( 327 PyInterpreterConfig *config, 328 long *maybe_whence, 329 PyThreadState **p_tstate, 330 PyThreadState **p_save_tstate); 331 PyAPI_FUNC(void) _PyXI_EndInterpreter( 332 PyInterpreterState *interp, 333 PyThreadState *tstate, 334 PyThreadState **p_save_tstate); 335 336 337 #ifdef __cplusplus 338 } 339 #endif 340 #endif /* !Py_INTERNAL_CROSSINTERP_H */ 341