Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-19 09:50:45

0001 #ifndef Py_INTERNAL_CROSSINTERP_H
0002 #define Py_INTERNAL_CROSSINTERP_H
0003 #ifdef __cplusplus
0004 extern "C" {
0005 #endif
0006 
0007 #ifndef Py_BUILD_CORE
0008 #  error "this header requires Py_BUILD_CORE define"
0009 #endif
0010 
0011 #include "pycore_lock.h"            // PyMutex
0012 #include "pycore_pyerrors.h"
0013 
0014 /**************/
0015 /* exceptions */
0016 /**************/
0017 
0018 PyAPI_DATA(PyObject *) PyExc_InterpreterError;
0019 PyAPI_DATA(PyObject *) PyExc_InterpreterNotFoundError;
0020 
0021 
0022 /***************************/
0023 /* cross-interpreter calls */
0024 /***************************/
0025 
0026 typedef int (*_Py_simple_func)(void *);
0027 extern int _Py_CallInInterpreter(
0028     PyInterpreterState *interp,
0029     _Py_simple_func func,
0030     void *arg);
0031 extern int _Py_CallInInterpreterAndRawFree(
0032     PyInterpreterState *interp,
0033     _Py_simple_func func,
0034     void *arg);
0035 
0036 
0037 /**************************/
0038 /* cross-interpreter data */
0039 /**************************/
0040 
0041 typedef struct _xid _PyCrossInterpreterData;
0042 typedef PyObject *(*xid_newobjectfunc)(_PyCrossInterpreterData *);
0043 typedef void (*xid_freefunc)(void *);
0044 
0045 // _PyCrossInterpreterData is similar to Py_buffer as an effectively
0046 // opaque struct that holds data outside the object machinery.  This
0047 // is necessary to pass safely between interpreters in the same process.
0048 struct _xid {
0049     // data is the cross-interpreter-safe derivation of a Python object
0050     // (see _PyObject_GetCrossInterpreterData).  It will be NULL if the
0051     // new_object func (below) encodes the data.
0052     void *data;
0053     // obj is the Python object from which the data was derived.  This
0054     // is non-NULL only if the data remains bound to the object in some
0055     // way, such that the object must be "released" (via a decref) when
0056     // the data is released.  In that case the code that sets the field,
0057     // likely a registered "crossinterpdatafunc", is responsible for
0058     // ensuring it owns the reference (i.e. incref).
0059     PyObject *obj;
0060     // interp is the ID of the owning interpreter of the original
0061     // object.  It corresponds to the active interpreter when
0062     // _PyObject_GetCrossInterpreterData() was called.  This should only
0063     // be set by the cross-interpreter machinery.
0064     //
0065     // We use the ID rather than the PyInterpreterState to avoid issues
0066     // with deleted interpreters.  Note that IDs are never re-used, so
0067     // each one will always correspond to a specific interpreter
0068     // (whether still alive or not).
0069     int64_t interpid;
0070     // new_object is a function that returns a new object in the current
0071     // interpreter given the data.  The resulting object (a new
0072     // reference) will be equivalent to the original object.  This field
0073     // is required.
0074     xid_newobjectfunc new_object;
0075     // free is called when the data is released.  If it is NULL then
0076     // nothing will be done to free the data.  For some types this is
0077     // okay (e.g. bytes) and for those types this field should be set
0078     // to NULL.  However, for most the data was allocated just for
0079     // cross-interpreter use, so it must be freed when
0080     // _PyCrossInterpreterData_Release is called or the memory will
0081     // leak.  In that case, at the very least this field should be set
0082     // to PyMem_RawFree (the default if not explicitly set to NULL).
0083     // The call will happen with the original interpreter activated.
0084     xid_freefunc free;
0085 };
0086 
0087 PyAPI_FUNC(_PyCrossInterpreterData *) _PyCrossInterpreterData_New(void);
0088 PyAPI_FUNC(void) _PyCrossInterpreterData_Free(_PyCrossInterpreterData *data);
0089 
0090 #define _PyCrossInterpreterData_DATA(DATA) ((DATA)->data)
0091 #define _PyCrossInterpreterData_OBJ(DATA) ((DATA)->obj)
0092 #define _PyCrossInterpreterData_INTERPID(DATA) ((DATA)->interpid)
0093 // Users should not need getters for "new_object" or "free".
0094 
0095 
0096 /* defining cross-interpreter data */
0097 
0098 PyAPI_FUNC(void) _PyCrossInterpreterData_Init(
0099         _PyCrossInterpreterData *data,
0100         PyInterpreterState *interp, void *shared, PyObject *obj,
0101         xid_newobjectfunc new_object);
0102 PyAPI_FUNC(int) _PyCrossInterpreterData_InitWithSize(
0103         _PyCrossInterpreterData *,
0104         PyInterpreterState *interp, const size_t, PyObject *,
0105         xid_newobjectfunc);
0106 PyAPI_FUNC(void) _PyCrossInterpreterData_Clear(
0107         PyInterpreterState *, _PyCrossInterpreterData *);
0108 
0109 // Normally the Init* functions are sufficient.  The only time
0110 // additional initialization might be needed is to set the "free" func,
0111 // though that should be infrequent.
0112 #define _PyCrossInterpreterData_SET_FREE(DATA, FUNC) \
0113     do { \
0114         (DATA)->free = (FUNC); \
0115     } while (0)
0116 // Additionally, some shareable types are essentially light wrappers
0117 // around other shareable types.  The crossinterpdatafunc of the wrapper
0118 // can often be implemented by calling the wrapped object's
0119 // crossinterpdatafunc and then changing the "new_object" function.
0120 // We have _PyCrossInterpreterData_SET_NEW_OBJECT() here for that,
0121 // but might be better to have a function like
0122 // _PyCrossInterpreterData_AdaptToWrapper() instead.
0123 #define _PyCrossInterpreterData_SET_NEW_OBJECT(DATA, FUNC) \
0124     do { \
0125         (DATA)->new_object = (FUNC); \
0126     } while (0)
0127 
0128 
0129 /* using cross-interpreter data */
0130 
0131 PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *);
0132 PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *);
0133 PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *);
0134 PyAPI_FUNC(int) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *);
0135 PyAPI_FUNC(int) _PyCrossInterpreterData_ReleaseAndRawFree(_PyCrossInterpreterData *);
0136 
0137 
0138 /* cross-interpreter data registry */
0139 
0140 // For now we use a global registry of shareable classes.  An
0141 // alternative would be to add a tp_* slot for a class's
0142 // crossinterpdatafunc. It would be simpler and more efficient.
0143 
0144 typedef int (*crossinterpdatafunc)(PyThreadState *tstate, PyObject *,
0145                                    _PyCrossInterpreterData *);
0146 
0147 struct _xidregitem;
0148 
0149 struct _xidregitem {
0150     struct _xidregitem *prev;
0151     struct _xidregitem *next;
0152     /* This can be a dangling pointer, but only if weakref is set. */
0153     PyTypeObject *cls;
0154     /* This is NULL for builtin types. */
0155     PyObject *weakref;
0156     size_t refcount;
0157     crossinterpdatafunc getdata;
0158 };
0159 
0160 struct _xidregistry {
0161     int global;  /* builtin types or heap types */
0162     int initialized;
0163     PyMutex mutex;
0164     struct _xidregitem *head;
0165 };
0166 
0167 PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc);
0168 PyAPI_FUNC(int) _PyCrossInterpreterData_UnregisterClass(PyTypeObject *);
0169 PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *);
0170 
0171 
0172 /*****************************/
0173 /* runtime state & lifecycle */
0174 /*****************************/
0175 
0176 struct _xi_runtime_state {
0177     // builtin types
0178     // XXX Remove this field once we have a tp_* slot.
0179     struct _xidregistry registry;
0180 };
0181 
0182 struct _xi_state {
0183     // heap types
0184     // XXX Remove this field once we have a tp_* slot.
0185     struct _xidregistry registry;
0186 
0187     // heap types
0188     PyObject *PyExc_NotShareableError;
0189 };
0190 
0191 extern PyStatus _PyXI_Init(PyInterpreterState *interp);
0192 extern void _PyXI_Fini(PyInterpreterState *interp);
0193 
0194 extern PyStatus _PyXI_InitTypes(PyInterpreterState *interp);
0195 extern void _PyXI_FiniTypes(PyInterpreterState *interp);
0196 
0197 #define _PyInterpreterState_GetXIState(interp) (&(interp)->xi)
0198 
0199 
0200 /***************************/
0201 /* short-term data sharing */
0202 /***************************/
0203 
0204 // Ultimately we'd like to preserve enough information about the
0205 // exception and traceback that we could re-constitute (or at least
0206 // simulate, a la traceback.TracebackException), and even chain, a copy
0207 // of the exception in the calling interpreter.
0208 
0209 typedef struct _excinfo {
0210     struct _excinfo_type {
0211         PyTypeObject *builtin;
0212         const char *name;
0213         const char *qualname;
0214         const char *module;
0215     } type;
0216     const char *msg;
0217     const char *errdisplay;
0218 } _PyXI_excinfo;
0219 
0220 PyAPI_FUNC(int) _PyXI_InitExcInfo(_PyXI_excinfo *info, PyObject *exc);
0221 PyAPI_FUNC(PyObject *) _PyXI_FormatExcInfo(_PyXI_excinfo *info);
0222 PyAPI_FUNC(PyObject *) _PyXI_ExcInfoAsObject(_PyXI_excinfo *info);
0223 PyAPI_FUNC(void) _PyXI_ClearExcInfo(_PyXI_excinfo *info);
0224 
0225 
0226 typedef enum error_code {
0227     _PyXI_ERR_NO_ERROR = 0,
0228     _PyXI_ERR_UNCAUGHT_EXCEPTION = -1,
0229     _PyXI_ERR_OTHER = -2,
0230     _PyXI_ERR_NO_MEMORY = -3,
0231     _PyXI_ERR_ALREADY_RUNNING = -4,
0232     _PyXI_ERR_MAIN_NS_FAILURE = -5,
0233     _PyXI_ERR_APPLY_NS_FAILURE = -6,
0234     _PyXI_ERR_NOT_SHAREABLE = -7,
0235 } _PyXI_errcode;
0236 
0237 
0238 typedef struct _sharedexception {
0239     // The originating interpreter.
0240     PyInterpreterState *interp;
0241     // The kind of error to propagate.
0242     _PyXI_errcode code;
0243     // The exception information to propagate, if applicable.
0244     // This is populated only for some error codes,
0245     // but always for _PyXI_ERR_UNCAUGHT_EXCEPTION.
0246     _PyXI_excinfo uncaught;
0247 } _PyXI_error;
0248 
0249 PyAPI_FUNC(PyObject *) _PyXI_ApplyError(_PyXI_error *err);
0250 
0251 
0252 typedef struct xi_session _PyXI_session;
0253 typedef struct _sharedns _PyXI_namespace;
0254 
0255 PyAPI_FUNC(void) _PyXI_FreeNamespace(_PyXI_namespace *ns);
0256 PyAPI_FUNC(_PyXI_namespace *) _PyXI_NamespaceFromNames(PyObject *names);
0257 PyAPI_FUNC(int) _PyXI_FillNamespaceFromDict(
0258     _PyXI_namespace *ns,
0259     PyObject *nsobj,
0260     _PyXI_session *session);
0261 PyAPI_FUNC(int) _PyXI_ApplyNamespace(
0262     _PyXI_namespace *ns,
0263     PyObject *nsobj,
0264     PyObject *dflt);
0265 
0266 
0267 // A cross-interpreter session involves entering an interpreter
0268 // (_PyXI_Enter()), doing some work with it, and finally exiting
0269 // that interpreter (_PyXI_Exit()).
0270 //
0271 // At the boundaries of the session, both entering and exiting,
0272 // data may be exchanged between the previous interpreter and the
0273 // target one in a thread-safe way that does not violate the
0274 // isolation between interpreters.  This includes setting objects
0275 // in the target's __main__ module on the way in, and capturing
0276 // uncaught exceptions on the way out.
0277 struct xi_session {
0278     // Once a session has been entered, this is the tstate that was
0279     // current before the session.  If it is different from cur_tstate
0280     // then we must have switched interpreters.  Either way, this will
0281     // be the current tstate once we exit the session.
0282     PyThreadState *prev_tstate;
0283     // Once a session has been entered, this is the current tstate.
0284     // It must be current when the session exits.
0285     PyThreadState *init_tstate;
0286     // This is true if init_tstate needs cleanup during exit.
0287     int own_init_tstate;
0288 
0289     // This is true if, while entering the session, init_thread took
0290     // "ownership" of the interpreter's __main__ module.  This means
0291     // it is the only thread that is allowed to run code there.
0292     // (Caveat: for now, users may still run exec() against the
0293     // __main__ module's dict, though that isn't advisable.)
0294     int running;
0295     // This is a cached reference to the __dict__ of the entered
0296     // interpreter's __main__ module.  It is looked up when at the
0297     // beginning of the session as a convenience.
0298     PyObject *main_ns;
0299 
0300     // This is set if the interpreter is entered and raised an exception
0301     // that needs to be handled in some special way during exit.
0302     _PyXI_errcode *error_override;
0303     // This is set if exit captured an exception to propagate.
0304     _PyXI_error *error;
0305 
0306     // -- pre-allocated memory --
0307     _PyXI_error _error;
0308     _PyXI_errcode _error_override;
0309 };
0310 
0311 PyAPI_FUNC(int) _PyXI_Enter(
0312     _PyXI_session *session,
0313     PyInterpreterState *interp,
0314     PyObject *nsupdates);
0315 PyAPI_FUNC(void) _PyXI_Exit(_PyXI_session *session);
0316 
0317 PyAPI_FUNC(PyObject *) _PyXI_ApplyCapturedException(_PyXI_session *session);
0318 PyAPI_FUNC(int) _PyXI_HasCapturedException(_PyXI_session *session);
0319 
0320 
0321 /*************/
0322 /* other API */
0323 /*************/
0324 
0325 // Export for _testinternalcapi shared extension
0326 PyAPI_FUNC(PyInterpreterState *) _PyXI_NewInterpreter(
0327     PyInterpreterConfig *config,
0328     long *maybe_whence,
0329     PyThreadState **p_tstate,
0330     PyThreadState **p_save_tstate);
0331 PyAPI_FUNC(void) _PyXI_EndInterpreter(
0332     PyInterpreterState *interp,
0333     PyThreadState *tstate,
0334     PyThreadState **p_save_tstate);
0335 
0336 
0337 #ifdef __cplusplus
0338 }
0339 #endif
0340 #endif /* !Py_INTERNAL_CROSSINTERP_H */