| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -65,6 +65,79 @@ PyAPI_FUNC(_PyInitError) _PyPathConfig_Calculate( | |
| PyAPI_FUNC(void) _PyPathConfig_Clear(_PyPathConfig *config); | ||
|
|
||
|
|
||
| /* interpreter state */ | ||
|
|
||
| PyAPI_FUNC(PyInterpreterState *) _PyInterpreterState_LookUpID(PY_INT64_T); | ||
|
|
||
|
|
||
| /* cross-interpreter data */ | ||
|
|
||
| struct _xid; | ||
|
|
||
| // _PyCrossInterpreterData is similar to Py_buffer as an effectively | ||
| // opaque struct that holds data outside the object machinery. This | ||
| // is necessary to pass between interpreters in the same process. | ||
| typedef struct _xid { | ||
| // data is the cross-interpreter-safe derivation of a Python object | ||
| // (see _PyObject_GetCrossInterpreterData). It will be NULL if the | ||
| // new_object func (below) encodes the data. | ||
| void *data; | ||
| // obj is the Python object from which the data was derived. This | ||
| // is non-NULL only if the data remains bound to the object in some | ||
| // way, such that the object must be "released" (via a decref) when | ||
| // the data is released. In that case it is automatically | ||
| // incref'ed (to match the automatic decref when releaed). | ||
| PyObject *obj; | ||
| // interp is the ID of the owning interpreter of the original | ||
| // object. It corresponds to the active interpreter when | ||
| // _PyObject_GetCrossInterpreterData() was called. This should only | ||
| // be set by the cross-interpreter machinery. | ||
| // | ||
| // We use the ID rather than the PyInterpreterState to avoid issues | ||
| // with deleted interpreters. | ||
| int64_t interp; | ||
| // new_object is a function that returns a new object in the current | ||
| // interpreter given the data. The resulting object (a new | ||
| // reference) will be equivalent to the original object. This field | ||
| // is required. | ||
| PyObject *(*new_object)(struct _xid *); | ||
| // free is called when the data is released. If it is NULL then | ||
| // nothing will be done to free the data. For some types this is | ||
| // okay (e.g. bytes) and for those types this field should be set | ||
| // to NULL. However, for most the data was allocated just for | ||
| // cross-interpreter use, so it must be freed when | ||
| // _PyCrossInterpreterData_Release is called or the memory will | ||
| // leak. In that case, at the very least this field should be set | ||
| // to PyMem_RawFree (the default if not explicitly set to NULL). | ||
| // The call will happen with the original interpreter activated. | ||
| void (*free)(void *); | ||
| } _PyCrossInterpreterData; | ||
|
Comment thread
Outdated
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityThe actual layout of the struct should go into an "internal" header file: "Include/pystate.h": typedef struct _xid _PyCrossInterpreterData;"Include/internal/pystate.h": struct _xid {
void *data;
// etc
}
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI haven't touched Include/pystate.h. If you are suggesting that I move the typedef (but not the layout) there, I don't see any benefit to that for 3.7. This is not a public API for now.
Sorry, something went wrong.
All reactions
|
||
|
|
||
| typedef int (*crossinterpdatafunc)(PyObject *, _PyCrossInterpreterData *); | ||
| PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *); | ||
|
|
||
| PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *); | ||
| PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *); | ||
| PyAPI_FUNC(void) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *); | ||
|
|
||
| /* cross-interpreter data registry */ | ||
|
|
||
| /* For now we use a global registry of shareable classes. An | ||
| alternative would be to add a tp_* slot for a class's | ||
| crossinterpdatafunc. It would be simpler and more efficient. */ | ||
|
|
||
| PyAPI_FUNC(int) _PyCrossInterpreterData_Register_Class(PyTypeObject *, crossinterpdatafunc); | ||
| PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *); | ||
|
|
||
| struct _xidregitem; | ||
|
|
||
| struct _xidregitem { | ||
| PyTypeObject *cls; | ||
| crossinterpdatafunc getdata; | ||
| struct _xidregitem *next; | ||
| }; | ||
|
|
||
|
|
||
| /* Full Python runtime state */ | ||
|
|
||
| typedef struct pyruntimestate { | ||
| Expand All | @@ -86,6 +159,11 @@ typedef struct pyruntimestate { | |
| using a Python int. */ | ||
| int64_t next_id; | ||
| } interpreters; | ||
| // XXX Remove this field once we have a tp_* slot. | ||
| struct _xidregistry { | ||
| PyThread_type_lock mutex; | ||
| struct _xidregitem *head; | ||
| } xidregistry; | ||
|
|
||
| #define NEXITFUNCS 32 | ||
| void (*exitfuncs[NEXITFUNCS])(void); | ||
| Expand Down | ||
| Back | FazBrowse Home | New Git URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualitySomething we'll need to keep an eye on here is not re-using interpreter IDs within the life of a process (otherwise we'll still run into issues with deleted interpreters).
Not that I've ever worked on systems where we introduced bugs by adding a freelist for objects where we assumed IDs would never be re-used or anything ;)
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityWe picked int64_t so that it was both really large and would overflow to negative. When the next ID is negative PyInterpreterState_New() raises RuntimError.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.