gh-76785: Crossinterp utils additions (gh-111530)

This moves several general internal APIs out of _xxsubinterpretersmodule.c and into the new Python/crossinterp.c (and the corresponding internal headers).

Specifically:

* _Py_excinfo, etc.:  the initial implementation for non-object exception snapshots (in pycore_pyerrors.h and Python/errors.c)
* _PyXI_exception_info, etc.:  helpers for passing an exception beween interpreters (wraps _Py_excinfo)
* _PyXI_namespace, etc.:  helpers for copying a dict of attrs between interpreters
* _PyXI_Enter(), _PyXI_Exit():  functions that abstract out the transitions between one interpreter and a second that will do some work temporarily

Again, these were all abstracted out of _xxsubinterpretersmodule.c as generalizations.  I plan on proposing these as public API at some point.
This commit is contained in:
Eric Snow 2023-11-01 17:36:40 -06:00 committed by GitHub
parent cde1071b2a
commit 9322ce90ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 1309 additions and 472 deletions

View file

@ -382,7 +382,7 @@ _Py_COMP_DIAG_POP
#define LOCKS_INIT(runtime) \
{ \
&(runtime)->interpreters.mutex, \
&(runtime)->xidregistry.mutex, \
&(runtime)->xi.registry.mutex, \
&(runtime)->getargs.mutex, \
&(runtime)->unicode_state.ids.lock, \
&(runtime)->imports.extensions.mutex, \
@ -494,9 +494,6 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
return _PyStatus_OK();
}
// This is defined in crossinterp.c (for now).
extern void _Py_xidregistry_clear(struct _xidregistry *);
void
_PyRuntimeState_Fini(_PyRuntimeState *runtime)
{
@ -505,8 +502,6 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime)
assert(runtime->object_state.interpreter_leaks == 0);
#endif
_Py_xidregistry_clear(&runtime->xidregistry);
if (gilstate_tss_initialized(runtime)) {
gilstate_tss_fini(runtime);
}
@ -552,11 +547,6 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
for (int i = 0; i < NUMLOCKS; i++) {
reinit_err += _PyThread_at_fork_reinit(lockptrs[i]);
}
/* PyOS_AfterFork_Child(), which calls this function, later calls
_PyInterpreterState_DeleteExceptMain(), so we only need to update
the main interpreter here. */
assert(runtime->interpreters.main != NULL);
runtime->interpreters.main->xidregistry.mutex = runtime->xidregistry.mutex;
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
@ -720,9 +710,6 @@ init_interpreter(PyInterpreterState *interp,
}
interp->f_opcode_trace_set = false;
assert(runtime->xidregistry.mutex != NULL);
interp->xidregistry.mutex = runtime->xidregistry.mutex;
interp->_initialized = 1;
return _PyStatus_OK();
}
@ -948,10 +935,6 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate)
Py_CLEAR(interp->sysdict);
Py_CLEAR(interp->builtins);
_Py_xidregistry_clear(&interp->xidregistry);
/* The lock is owned by the runtime, so we don't free it here. */
interp->xidregistry.mutex = NULL;
if (tstate->interp == interp) {
/* We are now safe to fix tstate->_status.cleared. */
// XXX Do this (much) earlier?