summaryrefslogtreecommitdiffstats
path: root/Include/internal/pycore_interp.h
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2023-10-04 22:35:27 (GMT)
committerGitHub <noreply@github.com>2023-10-04 22:35:27 (GMT)
commit80dc39e1dc2abc809f448cba5d2c5b9c1c631e11 (patch)
treeb34868d1758ef90007c4e0b1ff46a4156dfee4d6 /Include/internal/pycore_interp.h
parente561e9805854980a61967d07869b4ec4205b32c8 (diff)
downloadcpython-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.h44
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 *);