diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2023-10-04 22:35:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-04 22:35:27 (GMT) |
commit | 80dc39e1dc2abc809f448cba5d2c5b9c1c631e11 (patch) | |
tree | b34868d1758ef90007c4e0b1ff46a4156dfee4d6 /Include/internal/pycore_interp.h | |
parent | e561e9805854980a61967d07869b4ec4205b32c8 (diff) | |
download | cpython-80dc39e1dc2abc809f448cba5d2c5b9c1c631e11.zip cpython-80dc39e1dc2abc809f448cba5d2c5b9c1c631e11.tar.gz cpython-80dc39e1dc2abc809f448cba5d2c5b9c1c631e11.tar.bz2 |
gh-110310: Add a Per-Interpreter XID Registry for Heap Types (gh-110311)
We do the following:
* add a per-interpreter XID registry (PyInterpreterState.xidregistry)
* put heap types there (keep static types in _PyRuntimeState.xidregistry)
* clear the registries during interpreter/runtime finalization
* avoid duplicate entries in the registry (when _PyCrossInterpreterData_RegisterClass() is called more than once for a type)
* use Py_TYPE() instead of PyObject_Type() in _PyCrossInterpreterData_Lookup()
The per-interpreter registry helps preserve isolation between interpreters. This is important when heap types are registered, which is something we haven't been doing yet but I will likely do soon.
Diffstat (limited to 'Include/internal/pycore_interp.h')
-rw-r--r-- | Include/internal/pycore_interp.h | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 21d1ee3..523dfdc 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -39,6 +39,32 @@ struct _Py_long_state { int max_str_digits; }; + +/* 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. */ + +struct _xidregitem; + +struct _xidregitem { + struct _xidregitem *prev; + struct _xidregitem *next; + /* This can be a dangling pointer, but only if weakref is set. */ + PyTypeObject *cls; + /* This is NULL for builtin types. */ + PyObject *weakref; + size_t refcount; + crossinterpdatafunc getdata; +}; + +struct _xidregistry { + PyThread_type_lock mutex; + struct _xidregitem *head; +}; + + /* interpreter state */ /* PyInterpreterState holds the global state for one of the runtime's @@ -149,6 +175,9 @@ struct _is { Py_ssize_t co_extra_user_count; freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS]; + // XXX Remove this field once we have a tp_* slot. + struct _xidregistry xidregistry; + #ifdef HAVE_FORK PyObject *before_forkers; PyObject *after_forkers_parent; @@ -238,21 +267,6 @@ _PyInterpreterState_SetFinalizing(PyInterpreterState *interp, PyThreadState *tst } -/* 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. */ - -struct _xidregitem; - -struct _xidregitem { - struct _xidregitem *prev; - struct _xidregitem *next; - PyObject *cls; // weakref to a PyTypeObject - crossinterpdatafunc getdata; -}; - extern PyInterpreterState* _PyInterpreterState_LookUpID(int64_t); extern int _PyInterpreterState_IDInitref(PyInterpreterState *); |