Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions Include/internal/pycore_interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ struct _Py_long_state {
int max_str_digits;
};

struct _getargs_runtime_state {
struct _PyArg_Parser *static_parsers;
};


/* cross-interpreter data registry */

Expand Down Expand Up @@ -175,6 +179,7 @@ struct _is {
PyObject *after_forkers_child;
#endif

struct _getargs_runtime_state getargs;
struct _warnings_runtime_state warnings;
struct atexit_state atexit;

Expand Down
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
6 changes: 0 additions & 6 deletions Include/internal/pycore_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ extern "C" {
#include "pycore_typeobject.h" // struct types_runtime_state
#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids

struct _getargs_runtime_state {
PyThread_type_lock mutex;
Copy link
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;
};

/* GIL state */

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

#include <ctype.h>
#include <float.h>
Expand Down Expand Up @@ -2021,8 +2023,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 +2038,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 +2937,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
Original file line number Diff line number Diff line change
Expand Up @@ -380,12 +380,11 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
static const _PyRuntimeState initial = _PyRuntimeState_INIT(_PyRuntime);
_Py_COMP_DIAG_POP

#define NUMLOCKS 9
#define NUMLOCKS 8
#define LOCKS_INIT(runtime) \
{ \
&(runtime)->interpreters.mutex, \
&(runtime)->xidregistry.mutex, \
&(runtime)->getargs.mutex, \
&(runtime)->unicode_state.ids.lock, \
&(runtime)->imports.extensions.mutex, \
&(runtime)->ceval.pending_mainthread.lock, \
Expand Down Expand Up @@ -887,6 +886,8 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate)
_PyWarnings_Fini(interp);
_PyAtExit_Fini(interp);

_PyArg_Fini(interp);

// All Python types must be destroyed before the last GC collection. Python
// types create a reference cycle to themselves in their in their
// PyTypeObject.tp_mro member (the tuple contains the type).
Expand Down