]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-111971: Make _PyUnicode_FromId thread-safe in --disable-gil (gh-113489)
authorDonghee Na <donghee.na@python.org>
Tue, 26 Dec 2023 16:48:33 +0000 (16:48 +0000)
committerGitHub <noreply@github.com>
Tue, 26 Dec 2023 16:48:33 +0000 (16:48 +0000)
Include/cpython/object.h
Objects/unicodeobject.c

index 762e8a3b86ee1e535fec4b1162580797ff31e975..d6482f4bc689a1ba62257aa00bbe3d51bda41de8 100644 (file)
@@ -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
index ad87206b2a82001bac6e3ad54f3b0564844e8eb7..4b03cc3f4da5fab9b92e93c20cd16b82c03e3df0 100644 (file)
@@ -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;
 }