mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
GH-95909: Make _PyArg_Parser
initialization thread safe (GH-95958)
This commit is contained in:
parent
48174fa0b9
commit
9b30b965f0
3 changed files with 48 additions and 12 deletions
|
@ -1974,15 +1974,10 @@ new_kwtuple(const char * const *keywords, int total, int pos)
|
|||
}
|
||||
|
||||
static int
|
||||
parser_init(struct _PyArg_Parser *parser)
|
||||
_parser_init(struct _PyArg_Parser *parser)
|
||||
{
|
||||
const char * const *keywords = parser->keywords;
|
||||
assert(keywords != NULL);
|
||||
|
||||
if (parser->initialized) {
|
||||
assert(parser->kwtuple != NULL);
|
||||
return 1;
|
||||
}
|
||||
assert(parser->pos == 0 &&
|
||||
(parser->format == NULL || parser->fname == NULL) &&
|
||||
parser->custom_msg == NULL &&
|
||||
|
@ -2035,6 +2030,28 @@ parser_init(struct _PyArg_Parser *parser)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
parser_init(struct _PyArg_Parser *parser)
|
||||
{
|
||||
// volatile as it can be modified by other threads
|
||||
// and should not be optimized or reordered by compiler
|
||||
if (*((volatile int *)&parser->initialized)) {
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
parser_clear(struct _PyArg_Parser *parser)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue