Skip to content

Commit 093460d

Browse files
corona10aisk
authored andcommitted
pythongh-111971: Make _PyUnicode_FromId thread-safe in --disable-gil (pythongh-113489)
1 parent 2ab1f04 commit 093460d

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

Include/cpython/object.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ typedef struct _Py_Identifier {
3939
// Index in PyInterpreterState.unicode.ids.array. It is process-wide
4040
// unique and must be initialized to -1.
4141
Py_ssize_t index;
42+
// Hidden PyMutex struct for non free-threaded build.
43+
struct {
44+
uint8_t v;
45+
} mutex;
4246
} _Py_Identifier;
4347

4448
#ifndef Py_BUILD_CORE

Objects/unicodeobject.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,6 +1897,7 @@ PyUnicode_FromString(const char *u)
18971897
PyObject *
18981898
_PyUnicode_FromId(_Py_Identifier *id)
18991899
{
1900+
PyMutex_Lock((PyMutex *)&id->mutex);
19001901
PyInterpreterState *interp = _PyInterpreterState_GET();
19011902
struct _Py_unicode_ids *ids = &interp->unicode.ids;
19021903

@@ -1923,14 +1924,14 @@ _PyUnicode_FromId(_Py_Identifier *id)
19231924
obj = ids->array[index];
19241925
if (obj) {
19251926
// Return a borrowed reference
1926-
return obj;
1927+
goto end;
19271928
}
19281929
}
19291930

19301931
obj = PyUnicode_DecodeUTF8Stateful(id->string, strlen(id->string),
19311932
NULL, NULL);
19321933
if (!obj) {
1933-
return NULL;
1934+
goto end;
19341935
}
19351936
PyUnicode_InternInPlace(&obj);
19361937

@@ -1941,7 +1942,8 @@ _PyUnicode_FromId(_Py_Identifier *id)
19411942
PyObject **new_array = PyMem_Realloc(ids->array, new_size * item_size);
19421943
if (new_array == NULL) {
19431944
PyErr_NoMemory();
1944-
return NULL;
1945+
obj = NULL;
1946+
goto end;
19451947
}
19461948
memset(&new_array[ids->size], 0, (new_size - ids->size) * item_size);
19471949
ids->array = new_array;
@@ -1951,6 +1953,8 @@ _PyUnicode_FromId(_Py_Identifier *id)
19511953
// The array stores a strong reference
19521954
ids->array[index] = obj;
19531955

1956+
end:
1957+
PyMutex_Unlock((PyMutex *)&id->mutex);
19541958
// Return a borrowed reference
19551959
return obj;
19561960
}

0 commit comments

Comments
 (0)