From 0fd2c300c2a85b3b227a907b2a39ef79fa86d850 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 4 Jun 2019 03:15:09 +0200 Subject: [PATCH] Revert "bpo-36818: Add PyInterpreterState.runtime field. (gh-13129)" (GH-13795) This reverts commit 396e0a8d9dc65453cb9d53500d0a620602656cfe. --- Include/cpython/pystate.h | 6 +- Include/internal/pycore_object.h | 7 +- Include/internal/pycore_pylifecycle.h | 10 ++- Include/internal/pycore_pystate.h | 12 +-- .../2019-05-06-14-46-48.bpo-36818.5UDDLj.rst | 1 - Modules/_threadmodule.c | 2 +- Python/ceval.c | 26 +++--- Python/import.c | 3 +- Python/pylifecycle.c | 15 ++-- Python/pystate.c | 89 ++++++++++--------- Python/sysmodule.c | 31 ++++--- 11 files changed, 103 insertions(+), 99 deletions(-) delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 74e7fc96bec..94b0809cd4f 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -110,9 +110,9 @@ struct _ts { * if the thread holds the last reference to the lock, decref'ing the * lock will delete the lock, and that may trigger arbitrary Python code * if there's a weakref, with a callback, to the lock. But by this time - * _PyRuntimeState.gilstate.tstate_current is already NULL, so only the - * simplest of C code can be allowed to run (in particular it must not be - * possible to release the GIL). + * _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest + * of C code can be allowed to run (in particular it must not be possible to + * release the GIL). * So instead of holding the lock directly, the tstate holds a weakref to * the lock: that's the value of on_delete_data below. Decref'ing a * weakref is harmless. diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 1c5beb01f45..81548f81919 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -19,10 +19,9 @@ PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); * NB: While the object is tracked by the collector, it must be safe to call the * ob_traverse method. * - * Internal note: _PyRuntimeState.gc.generation0->_gc_prev doesn't have - * any bit flags because it's not object header. So we don't use - * _PyGCHead_PREV() and _PyGCHead_SET_PREV() for it to avoid unnecessary - * bitwise operations. + * Internal note: _PyRuntime.gc.generation0->_gc_prev doesn't have any bit flags + * because it's not object header. So we don't use _PyGCHead_PREV() and + * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations. * * The PyObject_GC_Track() function is the public version of this macro. */ diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index e30341710c2..8a692ea1649 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -39,10 +39,13 @@ extern PyStatus _PyFaulthandler_Init(int enable); extern int _PyTraceMalloc_Init(int enable); extern PyObject * _PyBuiltin_Init(void); extern PyStatus _PySys_Create( + _PyRuntimeState *runtime, PyInterpreterState *interp, PyObject **sysmod_p); extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict); -extern int _PySys_InitMain(PyInterpreterState *interp); +extern int _PySys_InitMain( + _PyRuntimeState *runtime, + PyInterpreterState *interp); extern PyStatus _PyImport_Init(PyInterpreterState *interp); extern PyStatus _PyExc_Init(void); extern PyStatus _PyErr_Init(void); @@ -83,7 +86,10 @@ extern void _PyHash_Fini(void); extern int _PyTraceMalloc_Fini(void); extern void _PyWarnings_Fini(PyInterpreterState *interp); -extern void _PyGILState_Init(PyThreadState *tstate); +extern void _PyGILState_Init( + _PyRuntimeState *runtime, + PyInterpreterState *interp, + PyThreadState *tstate); extern void _PyGILState_Fini(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyGC_DumpShutdownStats(_PyRuntimeState *runtime); diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 520a74b8a61..3ab4009770c 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -19,9 +19,6 @@ extern "C" { #include "pycore_pymem.h" #include "pycore_warnings.h" -// forward -struct pyruntimestate; - /* ceval state */ @@ -71,7 +68,6 @@ struct _is { struct _is *next; struct _ts *tstate_head; - struct pyruntimestate *runtime; int64_t id; int64_t id_refcount; @@ -300,8 +296,12 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void); /* Other */ -PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *tstate); -PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate); +PyAPI_FUNC(void) _PyThreadState_Init( + _PyRuntimeState *runtime, + PyThreadState *tstate); +PyAPI_FUNC(void) _PyThreadState_DeleteExcept( + _PyRuntimeState *runtime, + PyThreadState *tstate); PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap( struct _gilstate_runtime_state *gilstate, diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst deleted file mode 100644 index bb6c56a628e..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst +++ /dev/null @@ -1 +0,0 @@ -Add PyInterpreterState.runtime (and use it). diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 099afd86d05..d5e40ef999e 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -996,7 +996,7 @@ t_bootstrap(void *boot_raw) tstate = boot->tstate; tstate->thread_id = PyThread_get_thread_ident(); - _PyThreadState_Init(tstate); + _PyThreadState_Init(&_PyRuntime, tstate); PyEval_AcquireThread(tstate); tstate->interp->num_threads++; res = PyObject_Call(boot->func, boot->args, boot->keyw); diff --git a/Python/ceval.c b/Python/ceval.c index 2590ce6575a..7063647d584 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -238,9 +238,8 @@ _PyEval_FiniThreads(struct _ceval_runtime_state *ceval) } static inline void -exit_thread_if_finalizing(PyThreadState *tstate) +exit_thread_if_finalizing(_PyRuntimeState *runtime, PyThreadState *tstate) { - _PyRuntimeState *runtime = tstate->interp->runtime; /* _Py_Finalizing is protected by the GIL */ if (runtime->finalizing != NULL && !_Py_CURRENTLY_FINALIZING(runtime, tstate)) { drop_gil(&runtime->ceval, tstate); @@ -287,7 +286,7 @@ PyEval_AcquireLock(void) Py_FatalError("PyEval_AcquireLock: current thread state is NULL"); } take_gil(ceval, tstate); - exit_thread_if_finalizing(tstate); + exit_thread_if_finalizing(runtime, tstate); } void @@ -308,15 +307,14 @@ PyEval_AcquireThread(PyThreadState *tstate) if (tstate == NULL) { Py_FatalError("PyEval_AcquireThread: NULL new thread state"); } - assert(tstate->interp != NULL); - _PyRuntimeState *runtime = tstate->interp->runtime; + _PyRuntimeState *runtime = &_PyRuntime; struct _ceval_runtime_state *ceval = &runtime->ceval; /* Check someone has called PyEval_InitThreads() to create the lock */ assert(gil_created(&ceval->gil)); take_gil(ceval, tstate); - exit_thread_if_finalizing(tstate); + exit_thread_if_finalizing(runtime, tstate); if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { Py_FatalError("PyEval_AcquireThread: non-NULL old thread state"); } @@ -328,9 +326,8 @@ PyEval_ReleaseThread(PyThreadState *tstate) if (tstate == NULL) { Py_FatalError("PyEval_ReleaseThread: NULL thread state"); } - assert(tstate->interp != NULL); - _PyRuntimeState *runtime = tstate->interp->runtime; + _PyRuntimeState *runtime = &_PyRuntime; PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); if (new_tstate != tstate) { Py_FatalError("PyEval_ReleaseThread: wrong thread state"); @@ -361,7 +358,7 @@ _PyEval_ReInitThreads(_PyRuntimeState *runtime) } /* Destroy all threads except the current one */ - _PyThreadState_DeleteExcept(current_tstate); + _PyThreadState_DeleteExcept(runtime, current_tstate); } /* This function is used to signal that async exceptions are waiting to be @@ -390,18 +387,17 @@ PyEval_SaveThread(void) void PyEval_RestoreThread(PyThreadState *tstate) { + _PyRuntimeState *runtime = &_PyRuntime; + struct _ceval_runtime_state *ceval = &runtime->ceval; + if (tstate == NULL) { Py_FatalError("PyEval_RestoreThread: NULL tstate"); } - assert(tstate->interp != NULL); - - _PyRuntimeState *runtime = tstate->interp->runtime; - struct _ceval_runtime_state *ceval = &runtime->ceval; assert(gil_created(&ceval->gil)); int err = errno; take_gil(ceval, tstate); - exit_thread_if_finalizing(tstate); + exit_thread_if_finalizing(runtime, tstate); errno = err; _PyThreadState_Swap(&runtime->gilstate, tstate); @@ -1250,7 +1246,7 @@ main_loop: take_gil(ceval, tstate); /* Check if we should make a quick exit. */ - exit_thread_if_finalizing(tstate); + exit_thread_if_finalizing(runtime, tstate); if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { Py_FatalError("ceval: orphan tstate"); diff --git a/Python/import.c b/Python/import.c index 68d1f4003ab..ab7db6bc17f 100644 --- a/Python/import.c +++ b/Python/import.c @@ -541,8 +541,7 @@ PyImport_Cleanup(void) _PyGC_CollectNoFail(); /* Dump GC stats before it's too late, since it uses the warnings machinery. */ - _PyRuntimeState *runtime = interp->runtime; - _PyGC_DumpShutdownStats(runtime); + _PyGC_DumpShutdownStats(&_PyRuntime); /* Now, if there are any modules left alive, clear their globals to minimize potential leaks. All C extension modules actually end diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index fca2ee65519..751c4d6d1d6 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -545,7 +545,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime, _PyEval_FiniThreads(&runtime->ceval); /* Auto-thread-state API */ - _PyGILState_Init(tstate); + _PyGILState_Init(runtime, interp, tstate); /* Create the GIL */ PyEval_InitThreads(); @@ -683,7 +683,7 @@ pyinit_config(_PyRuntimeState *runtime, } PyObject *sysmod; - status = _PySys_Create(interp, &sysmod); + status = _PySys_Create(runtime, interp, &sysmod); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -892,9 +892,8 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp) * non-zero return code. */ static PyStatus -pyinit_main(PyInterpreterState *interp) +pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) { - _PyRuntimeState *runtime = interp->runtime; if (!runtime->core_initialized) { return _PyStatus_ERR("runtime core not initialized"); } @@ -920,7 +919,7 @@ pyinit_main(PyInterpreterState *interp) return _PyStatus_ERR("can't initialize time"); } - if (_PySys_InitMain(interp) < 0) { + if (_PySys_InitMain(runtime, interp) < 0) { return _PyStatus_ERR("can't finish initializing sys"); } @@ -1000,7 +999,7 @@ _Py_InitializeMain(void) _PyRuntimeState *runtime = &_PyRuntime; PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; - return pyinit_main(interp); + return pyinit_main(runtime, interp); } @@ -1027,7 +1026,7 @@ Py_InitializeFromConfig(const PyConfig *config) config = &interp->config; if (config->_init_main) { - status = pyinit_main(interp); + status = pyinit_main(runtime, interp); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1457,7 +1456,7 @@ new_interpreter(PyThreadState **tstate_p) } Py_INCREF(interp->sysdict); PyDict_SetItemString(interp->sysdict, "modules", modules); - if (_PySys_InitMain(interp) < 0) { + if (_PySys_InitMain(runtime, interp) < 0) { return _PyStatus_ERR("can't finish initializing sys"); } } diff --git a/Python/pystate.c b/Python/pystate.c index 2b7db0e48de..833e0fb30dc 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -39,6 +39,7 @@ extern "C" { /* Forward declarations */ static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); +static void _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate); static PyStatus @@ -191,8 +192,6 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime) PyInterpreterState * PyInterpreterState_New(void) { - _PyRuntimeState *runtime = &_PyRuntime; - if (PySys_Audit("cpython.PyInterpreterState_New", NULL) < 0) { return NULL; } @@ -203,9 +202,6 @@ PyInterpreterState_New(void) } memset(interp, 0, sizeof(*interp)); - - interp->runtime = runtime; - interp->id_refcount = -1; interp->check_interval = 100; @@ -227,6 +223,7 @@ PyInterpreterState_New(void) #endif #endif + _PyRuntimeState *runtime = &_PyRuntime; struct pyinterpreters *interpreters = &runtime->interpreters; HEAD_LOCK(runtime); @@ -260,11 +257,9 @@ PyInterpreterState_New(void) } -void -PyInterpreterState_Clear(PyInterpreterState *interp) +static void +_PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp) { - _PyRuntimeState *runtime = interp->runtime; - if (PySys_Audit("cpython.PyInterpreterState_Clear", NULL) < 0) { PyErr_Clear(); } @@ -302,25 +297,31 @@ PyInterpreterState_Clear(PyInterpreterState *interp) // objects have been cleaned up at the point. } +void +PyInterpreterState_Clear(PyInterpreterState *interp) +{ + _PyInterpreterState_Clear(&_PyRuntime, interp); +} + static void -zapthreads(PyInterpreterState *interp) +zapthreads(_PyRuntimeState *runtime, PyInterpreterState *interp) { - PyThreadState *ts; + PyThreadState *p; /* No need to lock the mutex here because this should only happen when the threads are all really dead (XXX famous last words). */ - while ((ts = interp->tstate_head) != NULL) { - PyThreadState_Delete(ts); + while ((p = interp->tstate_head) != NULL) { + _PyThreadState_Delete(runtime, p); } } -void -PyInterpreterState_Delete(PyInterpreterState *interp) +static void +_PyInterpreterState_Delete(_PyRuntimeState *runtime, + PyInterpreterState *interp) { - _PyRuntimeState *runtime = interp->runtime; struct pyinterpreters *interpreters = &runtime->interpreters; - zapthreads(interp); + zapthreads(runtime, interp); HEAD_LOCK(runtime); PyInterpreterState **p; for (p = &interpreters->head; ; p = &(*p)->next) { @@ -349,6 +350,13 @@ PyInterpreterState_Delete(PyInterpreterState *interp) } +void +PyInterpreterState_Delete(PyInterpreterState *interp) +{ + _PyInterpreterState_Delete(&_PyRuntime, interp); +} + + /* * Delete all interpreter states except the main interpreter. If there * is a current interpreter state, it *must* be the main interpreter. @@ -375,8 +383,8 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) continue; } - PyInterpreterState_Clear(interp); // XXX must activate? - zapthreads(interp); + _PyInterpreterState_Clear(runtime, interp); // XXX must activate? + zapthreads(runtime, interp); if (interp->id_mutex != NULL) { PyThread_free_lock(interp->id_mutex); } @@ -489,8 +497,7 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp) if (interp->id_mutex == NULL) { return; } - _PyRuntimeState *runtime = interp->runtime; - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); assert(interp->id_refcount != 0); interp->id_refcount -= 1; @@ -552,7 +559,7 @@ threadstate_getframe(PyThreadState *self) static PyThreadState * new_threadstate(PyInterpreterState *interp, int init) { - _PyRuntimeState *runtime = interp->runtime; + _PyRuntimeState *runtime = &_PyRuntime; PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); if (tstate == NULL) { return NULL; @@ -608,7 +615,7 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->id = ++interp->tstate_next_unique_id; if (init) { - _PyThreadState_Init(tstate); + _PyThreadState_Init(runtime, tstate); } HEAD_LOCK(runtime); @@ -635,9 +642,8 @@ _PyThreadState_Prealloc(PyInterpreterState *interp) } void -_PyThreadState_Init(PyThreadState *tstate) +_PyThreadState_Init(_PyRuntimeState *runtime, PyThreadState *tstate) { - _PyRuntimeState *runtime = tstate->interp->runtime; _PyGILState_NoteThreadState(&runtime->gilstate, tstate); } @@ -802,7 +808,7 @@ PyThreadState_Clear(PyThreadState *tstate) /* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */ static void -tstate_delete_common(PyThreadState *tstate) +tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate) { if (tstate == NULL) { Py_FatalError("PyThreadState_Delete: NULL tstate"); @@ -811,7 +817,6 @@ tstate_delete_common(PyThreadState *tstate) if (interp == NULL) { Py_FatalError("PyThreadState_Delete: NULL interp"); } - _PyRuntimeState *runtime = interp->runtime; HEAD_LOCK(runtime); if (tstate->prev) tstate->prev->next = tstate->next; @@ -827,10 +832,9 @@ tstate_delete_common(PyThreadState *tstate) } -void -PyThreadState_Delete(PyThreadState *tstate) +static void +_PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate) { - _PyRuntimeState *runtime = tstate->interp->runtime; struct _gilstate_runtime_state *gilstate = &runtime->gilstate; if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) { Py_FatalError("PyThreadState_Delete: tstate is still current"); @@ -840,7 +844,14 @@ PyThreadState_Delete(PyThreadState *tstate) { PyThread_tss_set(&gilstate->autoTSSkey, NULL); } - tstate_delete_common(tstate); + tstate_delete_common(runtime, tstate); +} + + +void +PyThreadState_Delete(PyThreadState *tstate) +{ + _PyThreadState_Delete(&_PyRuntime, tstate); } @@ -852,7 +863,7 @@ _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime) if (tstate == NULL) Py_FatalError( "PyThreadState_DeleteCurrent: no current tstate"); - tstate_delete_common(tstate); + tstate_delete_common(runtime, tstate); if (gilstate->autoInterpreterState && PyThread_tss_get(&gilstate->autoTSSkey) == tstate) { @@ -877,10 +888,9 @@ PyThreadState_DeleteCurrent() * be kept in those other interpreteres. */ void -_PyThreadState_DeleteExcept(PyThreadState *tstate) +_PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) { PyInterpreterState *interp = tstate->interp; - _PyRuntimeState *runtime = interp->runtime; PyThreadState *p, *next, *garbage; HEAD_LOCK(runtime); /* Remove all thread states, except tstate, from the linked list of @@ -1119,9 +1129,8 @@ _PyThread_CurrentFrames(void) static int PyThreadState_IsCurrent(PyThreadState *tstate) { - _PyRuntimeState *runtime = tstate->interp->runtime; /* Must be the tstate for this thread */ - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; + struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; assert(_PyGILState_GetThisThreadState(gilstate) == tstate); return tstate == _PyRuntimeGILState_GetThreadState(gilstate); } @@ -1130,14 +1139,12 @@ PyThreadState_IsCurrent(PyThreadState *tstate) Py_Initialize/Py_FinalizeEx */ void -_PyGILState_Init(PyThreadState *tstate) +_PyGILState_Init(_PyRuntimeState *runtime, + PyInterpreterState *interp, PyThreadState *tstate) { /* must init with valid states */ - assert(tstate != NULL); - PyInterpreterState *interp = tstate->interp; assert(interp != NULL); - _PyRuntimeState *runtime = interp->runtime; - assert(runtime != NULL); + assert(tstate != NULL); struct _gilstate_runtime_state *gilstate = &runtime->gilstate; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 97bff94d8b4..12b1bd7711d 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -120,9 +120,8 @@ should_audit(void) if (!ts) { return 0; } - PyInterpreterState *is = ts->interp; - _PyRuntimeState *runtime = is->runtime; - return runtime->audit_hook_head + PyInterpreterState *is = ts ? ts->interp : NULL; + return _PyRuntime.audit_hook_head || (is && is->audit_hooks) || PyDTrace_AUDIT_ENABLED(); } @@ -281,8 +280,8 @@ void _PySys_ClearAuditHooks(void) { PySys_Audit("cpython._PySys_ClearAuditHooks", NULL); PyErr_Clear(); - _Py_AuditHookEntry *e = runtime->audit_hook_head, *n; - runtime->audit_hook_head = NULL; + _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head, *n; + _PyRuntime.audit_hook_head = NULL; while (e) { n = e->next; PyMem_RawFree(e); @@ -293,7 +292,6 @@ void _PySys_ClearAuditHooks(void) { int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) { - _PyRuntimeState *runtime = &_PyRuntime; /* Invoke existing audit hooks to allow them an opportunity to abort. */ /* Cannot invoke hooks until we are initialized */ if (Py_IsInitialized()) { @@ -307,10 +305,10 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) } } - _Py_AuditHookEntry *e = runtime->audit_hook_head; + _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head; if (!e) { e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry)); - runtime->audit_hook_head = e; + _PyRuntime.audit_hook_head = e; } else { while (e->next) e = e->next; @@ -2415,9 +2413,8 @@ static PyStructSequence_Desc flags_desc = { }; static PyObject* -make_flags(PyInterpreterState *interp) +make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp) { - _PyRuntimeState *runtime = interp->runtime; int pos = 0; PyObject *seq; const PyPreConfig *preconfig = &runtime->preconfig; @@ -2636,7 +2633,8 @@ static struct PyModuleDef sysmodule = { } while (0) static PyStatus -_PySys_InitCore(PyInterpreterState *interp, PyObject *sysdict) +_PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, + PyObject *sysdict) { PyObject *version_info; int res; @@ -2730,7 +2728,7 @@ _PySys_InitCore(PyInterpreterState *interp, PyObject *sysdict) } } /* Set flags to their default values (updated by _PySys_InitMain()) */ - SET_SYS_FROM_STRING("flags", make_flags(interp)); + SET_SYS_FROM_STRING("flags", make_flags(runtime, interp)); #if defined(MS_WINDOWS) /* getwindowsversion */ @@ -2851,7 +2849,7 @@ sys_create_xoptions_dict(const PyConfig *config) int -_PySys_InitMain(PyInterpreterState *interp) +_PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) { PyObject *sysdict = interp->sysdict; const PyConfig *config = &interp->config; @@ -2905,7 +2903,7 @@ _PySys_InitMain(PyInterpreterState *interp) #undef SET_SYS_FROM_WSTR /* Set flags to their final values */ - SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(interp)); + SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(runtime, interp)); /* prevent user from creating new instances */ FlagsType.tp_init = NULL; FlagsType.tp_new = NULL; @@ -2972,7 +2970,8 @@ error: /* Create sys module without all attributes: _PySys_InitMain() should be called later to add remaining attributes. */ PyStatus -_PySys_Create(PyInterpreterState *interp, PyObject **sysmod_p) +_PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp, + PyObject **sysmod_p) { PyObject *modules = PyDict_New(); if (modules == NULL) { @@ -3001,7 +3000,7 @@ _PySys_Create(PyInterpreterState *interp, PyObject **sysmod_p) return status; } - status = _PySys_InitCore(interp, sysdict); + status = _PySys_InitCore(runtime, interp, sysdict); if (_PyStatus_EXCEPTION(status)) { return status; }