summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDonghee Na <donghee.na@python.org>2023-12-26 16:48:33 (GMT)
committerGitHub <noreply@github.com>2023-12-26 16:48:33 (GMT)
commit8f5b9987066f46daa67b622d913ff2c51c949ed4 (patch)
treeba31f7d886c3f97daeb9d424fe6809c439ea289d
parent36adc79041f4d2764e1daf7db5bb478923e89a1f (diff)
downloadcpython-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.h4
-rw-r--r--Objects/unicodeobject.c10
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;
}