summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorKirill Podoprigora <kirill.bast9@mail.ru>2023-11-30 10:12:49 (GMT)
committerGitHub <noreply@github.com>2023-11-30 10:12:49 (GMT)
commit0785c685599aaa052f85d6163872bdecb9c66486 (patch)
tree269bcf13cdd75f338d3539126d6dd0021846fdd7 /Objects
parent81261fa67ff82b03c255733b0d1abbbb8a228187 (diff)
downloadcpython-0785c685599aaa052f85d6163872bdecb9c66486.zip
cpython-0785c685599aaa052f85d6163872bdecb9c66486.tar.gz
cpython-0785c685599aaa052f85d6163872bdecb9c66486.tar.bz2
gh-111972: Make Unicode name C APIcapsule initialization thread-safe (#112249)
Diffstat (limited to 'Objects')
-rw-r--r--Objects/unicodeobject.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index cffc062..10022e2 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -5869,6 +5869,23 @@ PyUnicode_AsUTF16String(PyObject *unicode)
return _PyUnicode_EncodeUTF16(unicode, NULL, 0);
}
+_PyUnicode_Name_CAPI *
+_PyUnicode_GetNameCAPI(void)
+{
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ _PyUnicode_Name_CAPI *ucnhash_capi;
+
+ ucnhash_capi = _Py_atomic_load_ptr(&interp->unicode.ucnhash_capi);
+ if (ucnhash_capi == NULL) {
+ ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import(
+ PyUnicodeData_CAPSULE_NAME, 1);
+
+ // It's fine if we overwite the value here. It's always the same value.
+ _Py_atomic_store_ptr(&interp->unicode.ucnhash_capi, ucnhash_capi);
+ }
+ return ucnhash_capi;
+}
+
/* --- Unicode Escape Codec ----------------------------------------------- */
PyObject *
@@ -5884,7 +5901,6 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s,
PyObject *errorHandler = NULL;
PyObject *exc = NULL;
_PyUnicode_Name_CAPI *ucnhash_capi;
- PyInterpreterState *interp = _PyInterpreterState_GET();
// so we can remember if we've seen an invalid escape char or not
*first_invalid_escape = NULL;
@@ -6032,19 +6048,13 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s,
/* \N{name} */
case 'N':
- ucnhash_capi = interp->unicode.ucnhash_capi;
+ ucnhash_capi = _PyUnicode_GetNameCAPI();
if (ucnhash_capi == NULL) {
- /* load the unicode data module */
- ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import(
- PyUnicodeData_CAPSULE_NAME, 1);
- if (ucnhash_capi == NULL) {
- PyErr_SetString(
+ PyErr_SetString(
PyExc_UnicodeError,
"\\N escapes not supported (can't load unicodedata module)"
- );
- goto onError;
- }
- interp->unicode.ucnhash_capi = ucnhash_capi;
+ );
+ goto onError;
}
message = "malformed \\N character escape";