diff options
author | Donghee Na <donghee.na@python.org> | 2023-12-26 16:48:33 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-26 16:48:33 (GMT) |
commit | 8f5b9987066f46daa67b622d913ff2c51c949ed4 (patch) | |
tree | ba31f7d886c3f97daeb9d424fe6809c439ea289d | |
parent | 36adc79041f4d2764e1daf7db5bb478923e89a1f (diff) | |
download | cpython-8f5b9987066f46daa67b622d913ff2c51c949ed4.zip cpython-8f5b9987066f46daa67b622d913ff2c51c949ed4.tar.gz cpython-8f5b9987066f46daa67b622d913ff2c51c949ed4.tar.bz2 |
gh-111971: Make _PyUnicode_FromId thread-safe in --disable-gil (gh-113489)
-rw-r--r-- | Include/cpython/object.h | 4 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 10 |
2 files changed, 11 insertions, 3 deletions
diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 762e8a3..d6482f4 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -39,6 +39,10 @@ typedef struct _Py_Identifier { // Index in PyInterpreterState.unicode.ids.array. It is process-wide // unique and must be initialized to -1. Py_ssize_t index; + // Hidden PyMutex struct for non free-threaded build. + struct { + uint8_t v; + } mutex; } _Py_Identifier; #ifndef Py_BUILD_CORE diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index ad87206..4b03cc3 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1897,6 +1897,7 @@ PyUnicode_FromString(const char *u) PyObject * _PyUnicode_FromId(_Py_Identifier *id) { + PyMutex_Lock((PyMutex *)&id->mutex); PyInterpreterState *interp = _PyInterpreterState_GET(); struct _Py_unicode_ids *ids = &interp->unicode.ids; @@ -1923,14 +1924,14 @@ _PyUnicode_FromId(_Py_Identifier *id) obj = ids->array[index]; if (obj) { // Return a borrowed reference - return obj; + goto end; } } obj = PyUnicode_DecodeUTF8Stateful(id->string, strlen(id->string), NULL, NULL); if (!obj) { - return NULL; + goto end; } PyUnicode_InternInPlace(&obj); @@ -1941,7 +1942,8 @@ _PyUnicode_FromId(_Py_Identifier *id) PyObject **new_array = PyMem_Realloc(ids->array, new_size * item_size); if (new_array == NULL) { PyErr_NoMemory(); - return NULL; + obj = NULL; + goto end; } memset(&new_array[ids->size], 0, (new_size - ids->size) * item_size); ids->array = new_array; @@ -1951,6 +1953,8 @@ _PyUnicode_FromId(_Py_Identifier *id) // The array stores a strong reference ids->array[index] = obj; +end: + PyMutex_Unlock((PyMutex *)&id->mutex); // Return a borrowed reference return obj; } |