[3.12] gh-119213: Fix getargs.c to store state in InterpreterState... by 1st1 · Pull Request #119194 · python/cpython · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Include/internal/pycore_interp.h
3 changes: 2 additions & 1 deletion Include/internal/pycore_pylifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ extern void _PyAST_Fini(PyInterpreterState *interp);
extern void _PyAtExit_Fini(PyInterpreterState *interp);
extern void _PyThread_FiniType(PyInterpreterState *interp);
extern void _Py_Deepfreeze_Fini(void);
extern void _PyArg_Fini(void);
extern void _PyArg_InitState(PyInterpreterState *interp);
extern void _PyArg_Fini(PyInterpreterState *interp);
extern void _Py_FinalizeAllocatedBlocks(_PyRuntimeState *);

extern PyStatus _PyGILState_Init(PyInterpreterState *interp);
Expand Down
7 changes: 5 additions & 2 deletions Include/internal/pycore_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ extern "C" {
#include "pycore_typeobject.h" // struct types_runtime_state
#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids

struct _getargs_runtime_state {
/* The following struct is moved to interpreter state in 3.13+.
We're keeping it here for ABI compat.
See also: https://github.com/python/cpython/pull/119194. */
struct _UNUSED_getargs_runtime_state {
PyThread_type_lock mutex;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having a lock isn't necessary in 3.12 as we're muving this struct to InterpreterState. Local state modification will be protected by the GIL.

struct _PyArg_Parser *static_parsers;
};
Expand Down Expand Up @@ -135,7 +138,7 @@ typedef struct pyruntimestate {
struct _import_runtime_state imports;
struct _ceval_runtime_state ceval;
struct _gilstate_runtime_state gilstate;
struct _getargs_runtime_state getargs;
struct _UNUSED_getargs_runtime_state _UNUSED_gilstate;
struct _fileutils_state fileutils;
struct _faulthandler_runtime_state faulthandler;
struct _tracemalloc_runtime_state tracemalloc;
Expand Down
27 changes: 13 additions & 14 deletions Python/getargs.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "Python.h"
#include "pycore_tuple.h" // _PyTuple_ITEMS()
#include "pycore_pylifecycle.h" // _PyArg_Fini
#include "pycore_interp.h" // _getargs_runtime_state

#include <ctype.h>
#include <float.h>
Expand Down Expand Up @@ -2021,8 +2022,9 @@ _parser_init(struct _PyArg_Parser *parser)
parser->initialized = owned ? 1 : -1;

assert(parser->next == NULL);
parser->next = _PyRuntime.getargs.static_parsers;
_PyRuntime.getargs.static_parsers = parser;
PyInterpreterState *interp = PyInterpreterState_Get();
parser->next = interp->getargs.static_parsers;
interp->getargs.static_parsers = parser;
return 1;
}

Expand All @@ -2035,16 +2037,7 @@ parser_init(struct _PyArg_Parser *parser)
assert(parser->kwtuple != NULL);
return 1;
}
PyThread_acquire_lock(_PyRuntime.getargs.mutex, WAIT_LOCK);
// Check again if another thread initialized the parser
// while we were waiting for the lock.
if (*((volatile int *)&parser->initialized)) {
assert(parser->kwtuple != NULL);
PyThread_release_lock(_PyRuntime.getargs.mutex);
return 1;
}
int ret = _parser_init(parser);
PyThread_release_lock(_PyRuntime.getargs.mutex);
return ret;
}

Expand Down Expand Up @@ -2943,16 +2936,22 @@ _PyArg_NoKwnames(const char *funcname, PyObject *kwnames)
}

void
_PyArg_Fini(void)
_PyArg_InitState(PyInterpreterState *interp)
{
interp->getargs.static_parsers = NULL;
}

void
_PyArg_Fini(PyInterpreterState *interp)
{
struct _PyArg_Parser *tmp, *s = _PyRuntime.getargs.static_parsers;
struct _PyArg_Parser *tmp, *s = interp->getargs.static_parsers;
while (s) {
tmp = s->next;
s->next = NULL;
parser_clear(s);
s = tmp;
}
_PyRuntime.getargs.static_parsers = NULL;
interp->getargs.static_parsers = NULL;
}

#ifdef __cplusplus
Expand Down
3 changes: 2 additions & 1 deletion Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,8 @@ pycore_interp_init(PyThreadState *tstate)
return _PyStatus_ERR("can't initialize warnings");
}

_PyArg_InitState(interp);

status = _PyAtExit_Init(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
Expand Down Expand Up @@ -1751,7 +1753,6 @@ finalize_interp_clear(PyThreadState *tstate)

if (is_main_interp) {
_Py_HashRandomization_Fini();
_PyArg_Fini();
_Py_ClearFileSystemEncoding();
_Py_Deepfreeze_Fini();
_PyPerfTrampoline_Fini();
Expand Down
5 changes: 3 additions & 2 deletions Python/pystate.c