mirror of https://github.com/python/cpython
gh-111971: Make _PyUnicode_FromId thread-safe in --disable-gil (gh-113489)
This commit is contained in:
parent
36adc79041
commit
8f5b998706
|
@ -39,6 +39,10 @@ typedef struct _Py_Identifier {
|
||||||
// Index in PyInterpreterState.unicode.ids.array. It is process-wide
|
// Index in PyInterpreterState.unicode.ids.array. It is process-wide
|
||||||
// unique and must be initialized to -1.
|
// unique and must be initialized to -1.
|
||||||
Py_ssize_t index;
|
Py_ssize_t index;
|
||||||
|
// Hidden PyMutex struct for non free-threaded build.
|
||||||
|
struct {
|
||||||
|
uint8_t v;
|
||||||
|
} mutex;
|
||||||
} _Py_Identifier;
|
} _Py_Identifier;
|
||||||
|
|
||||||
#ifndef Py_BUILD_CORE
|
#ifndef Py_BUILD_CORE
|
||||||
|
|
|
@ -1897,6 +1897,7 @@ PyUnicode_FromString(const char *u)
|
||||||
PyObject *
|
PyObject *
|
||||||
_PyUnicode_FromId(_Py_Identifier *id)
|
_PyUnicode_FromId(_Py_Identifier *id)
|
||||||
{
|
{
|
||||||
|
PyMutex_Lock((PyMutex *)&id->mutex);
|
||||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||||
struct _Py_unicode_ids *ids = &interp->unicode.ids;
|
struct _Py_unicode_ids *ids = &interp->unicode.ids;
|
||||||
|
|
||||||
|
@ -1923,14 +1924,14 @@ _PyUnicode_FromId(_Py_Identifier *id)
|
||||||
obj = ids->array[index];
|
obj = ids->array[index];
|
||||||
if (obj) {
|
if (obj) {
|
||||||
// Return a borrowed reference
|
// Return a borrowed reference
|
||||||
return obj;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = PyUnicode_DecodeUTF8Stateful(id->string, strlen(id->string),
|
obj = PyUnicode_DecodeUTF8Stateful(id->string, strlen(id->string),
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
return NULL;
|
goto end;
|
||||||
}
|
}
|
||||||
PyUnicode_InternInPlace(&obj);
|
PyUnicode_InternInPlace(&obj);
|
||||||
|
|
||||||
|
@ -1941,7 +1942,8 @@ _PyUnicode_FromId(_Py_Identifier *id)
|
||||||
PyObject **new_array = PyMem_Realloc(ids->array, new_size * item_size);
|
PyObject **new_array = PyMem_Realloc(ids->array, new_size * item_size);
|
||||||
if (new_array == NULL) {
|
if (new_array == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
return NULL;
|
obj = NULL;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
memset(&new_array[ids->size], 0, (new_size - ids->size) * item_size);
|
memset(&new_array[ids->size], 0, (new_size - ids->size) * item_size);
|
||||||
ids->array = new_array;
|
ids->array = new_array;
|
||||||
|
@ -1951,6 +1953,8 @@ _PyUnicode_FromId(_Py_Identifier *id)
|
||||||
// The array stores a strong reference
|
// The array stores a strong reference
|
||||||
ids->array[index] = obj;
|
ids->array[index] = obj;
|
||||||
|
|
||||||
|
end:
|
||||||
|
PyMutex_Unlock((PyMutex *)&id->mutex);
|
||||||
// Return a borrowed reference
|
// Return a borrowed reference
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue