From 0e87b731ee7688e9737405ec8e771db9dc42ec91 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 25 Jun 2024 14:35:12 -0600 Subject: [PATCH] gh-120838: Add _PyThreadState_WHENCE_FINI (gh-121010) We also add _PyThreadState_NewBound() and drop _PyThreadState_SetWhence(). This change only affects internal API. --- Include/cpython/pystate.h | 9 +++++---- Include/internal/pycore_pystate.h | 6 +++++- Include/internal/pycore_tstate.h | 7 ------- Modules/_testinternalcapi.c | 4 ++-- Python/crossinterp.c | 6 ++---- Python/import.c | 4 ++-- Python/pylifecycle.c | 4 ++-- Python/pystate.c | 14 +++++++++----- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index ed3ee090ae53db8..bb2af78a376d751 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -97,10 +97,11 @@ struct _ts { #ifdef Py_BUILD_CORE # define _PyThreadState_WHENCE_NOTSET -1 # define _PyThreadState_WHENCE_UNKNOWN 0 -# define _PyThreadState_WHENCE_INTERP 1 -# define _PyThreadState_WHENCE_THREADING 2 -# define _PyThreadState_WHENCE_GILSTATE 3 -# define _PyThreadState_WHENCE_EXEC 4 +# define _PyThreadState_WHENCE_INIT 1 +# define _PyThreadState_WHENCE_FINI 2 +# define _PyThreadState_WHENCE_THREADING 3 +# define _PyThreadState_WHENCE_GILSTATE 4 +# define _PyThreadState_WHENCE_EXEC 5 #endif int _whence; diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index a668d78b969bd93..b0e72523f58ed8e 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -217,10 +217,14 @@ static inline PyInterpreterState* _PyInterpreterState_GET(void) { // PyThreadState functions -extern PyThreadState * _PyThreadState_New( +// Export for _testinternalcapi +PyAPI_FUNC(PyThreadState *) _PyThreadState_New( PyInterpreterState *interp, int whence); extern void _PyThreadState_Bind(PyThreadState *tstate); +PyAPI_FUNC(PyThreadState *) _PyThreadState_NewBound( + PyInterpreterState *interp, + int whence); extern PyThreadState * _PyThreadState_RemoveExcept(PyThreadState *tstate); extern void _PyThreadState_DeleteList(PyThreadState *list); extern void _PyThreadState_ClearMimallocHeaps(PyThreadState *tstate); diff --git a/Include/internal/pycore_tstate.h b/Include/internal/pycore_tstate.h index 733e3172a1c0ff6..befca950920bacd 100644 --- a/Include/internal/pycore_tstate.h +++ b/Include/internal/pycore_tstate.h @@ -14,13 +14,6 @@ extern "C" { #include "pycore_qsbr.h" // struct qsbr -static inline void -_PyThreadState_SetWhence(PyThreadState *tstate, int whence) -{ - tstate->_whence = whence; -} - - // Every PyThreadState is actually allocated as a _PyThreadStateImpl. The // PyThreadState fields are exposed as part of the C API, although most fields // are intended to be private. The _PyThreadStateImpl fields not exposed. diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 3dd40a66abc1a49..3366706e4c70473 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -1586,8 +1586,8 @@ exec_interpreter(PyObject *self, PyObject *args, PyObject *kwargs) } PyObject *res = NULL; - PyThreadState *tstate = PyThreadState_New(interp); - _PyThreadState_SetWhence(tstate, _PyThreadState_WHENCE_EXEC); + PyThreadState *tstate = + _PyThreadState_NewBound(interp, _PyThreadState_WHENCE_EXEC); PyThreadState *save_tstate = PyThreadState_Swap(tstate); diff --git a/Python/crossinterp.c b/Python/crossinterp.c index 367e29d40d895ad..a03456a8bbfd6f6 100644 --- a/Python/crossinterp.c +++ b/Python/crossinterp.c @@ -1544,8 +1544,7 @@ _enter_session(_PyXI_session *session, PyInterpreterState *interp) PyThreadState *tstate = PyThreadState_Get(); PyThreadState *prev = tstate; if (interp != tstate->interp) { - tstate = PyThreadState_New(interp); - _PyThreadState_SetWhence(tstate, _PyThreadState_WHENCE_EXEC); + tstate = _PyThreadState_NewBound(interp, _PyThreadState_WHENCE_EXEC); // XXX Possible GILState issues? session->prev_tstate = PyThreadState_Swap(tstate); assert(session->prev_tstate == prev); @@ -1895,8 +1894,7 @@ _PyXI_EndInterpreter(PyInterpreterState *interp, tstate = cur_tstate; } else { - tstate = PyThreadState_New(interp); - _PyThreadState_SetWhence(tstate, _PyThreadState_WHENCE_INTERP); + tstate = _PyThreadState_NewBound(interp, _PyThreadState_WHENCE_FINI); assert(tstate != NULL); save_tstate = PyThreadState_Swap(tstate); } diff --git a/Python/import.c b/Python/import.c index 366c0167d039767..20ad10020044df1 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1518,11 +1518,11 @@ switch_to_main_interpreter(PyThreadState *tstate) if (_Py_IsMainInterpreter(tstate->interp)) { return tstate; } - PyThreadState *main_tstate = PyThreadState_New(_PyInterpreterState_Main()); + PyThreadState *main_tstate = _PyThreadState_NewBound( + _PyInterpreterState_Main(), _PyThreadState_WHENCE_EXEC); if (main_tstate == NULL) { return NULL; } - main_tstate->_whence = _PyThreadState_WHENCE_EXEC; #ifndef NDEBUG PyThreadState *old_tstate = PyThreadState_Swap(main_tstate); assert(old_tstate == tstate); diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index a7b4d7ecc7c3ad3..9b599cba2414453 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -677,7 +677,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime, } PyThreadState *tstate = _PyThreadState_New(interp, - _PyThreadState_WHENCE_INTERP); + _PyThreadState_WHENCE_INIT); if (tstate == NULL) { return _PyStatus_ERR("can't make first thread"); } @@ -2233,7 +2233,7 @@ new_interpreter(PyThreadState **tstate_p, goto error; } - tstate = _PyThreadState_New(interp, _PyThreadState_WHENCE_INTERP); + tstate = _PyThreadState_New(interp, _PyThreadState_WHENCE_INIT); if (tstate == NULL) { status = _PyStatus_NO_MEMORY(); goto error; diff --git a/Python/pystate.c b/Python/pystate.c index 8d31a4db200d74e..602b13e18c71ae5 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1293,9 +1293,8 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp) PyThread_release_lock(interp->id_mutex); if (refcount == 0 && interp->requires_idref) { - PyThreadState *tstate = _PyThreadState_New(interp, - _PyThreadState_WHENCE_INTERP); - _PyThreadState_Bind(tstate); + PyThreadState *tstate = + _PyThreadState_NewBound(interp, _PyThreadState_WHENCE_FINI); // XXX Possible GILState issues? PyThreadState *save_tstate = _PyThreadState_Swap(runtime, tstate); @@ -1603,8 +1602,13 @@ new_threadstate(PyInterpreterState *interp, int whence) PyThreadState * PyThreadState_New(PyInterpreterState *interp) { - PyThreadState *tstate = new_threadstate(interp, - _PyThreadState_WHENCE_UNKNOWN); + return _PyThreadState_NewBound(interp, _PyThreadState_WHENCE_UNKNOWN); +} + +PyThreadState * +_PyThreadState_NewBound(PyInterpreterState *interp, int whence) +{ + PyThreadState *tstate = new_threadstate(interp, whence); if (tstate) { bind_tstate(tstate); // This makes sure there's a gilstate tstate bound