diff options
author | Dino Viehland <dinoviehland@meta.com> | 2024-02-06 22:03:43 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-06 22:03:43 (GMT) |
commit | 92abb0124037e5bc938fa870461a26f64c56095b (patch) | |
tree | 3f3e6789befc115364c2ab2e893084ba616e63a7 /Modules | |
parent | b6228b521b4692b2de1c1c12f4aa5623f8319084 (diff) | |
download | cpython-92abb0124037e5bc938fa870461a26f64c56095b.zip cpython-92abb0124037e5bc938fa870461a26f64c56095b.tar.gz cpython-92abb0124037e5bc938fa870461a26f64c56095b.tar.bz2 |
gh-112075: Add critical sections for most dict APIs (#114508)
Starts adding thread safety to dict objects.
Use @critical_section for APIs which are exposed via argument clinic and don't directly correlate with a public C API which needs to acquire the lock
Use a _lock_held suffix for keeping changes to complicated functions simple and just wrapping them with a critical section
Acquire and release the lock in an existing function where it won't be overly disruptive to the existing logic
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_sre/sre.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/Modules/_sre/sre.c b/Modules/_sre/sre.c index d451974..00fbd96 100644 --- a/Modules/_sre/sre.c +++ b/Modules/_sre/sre.c @@ -39,13 +39,14 @@ static const char copyright[] = " SRE 2.2.2 Copyright (c) 1997-2002 by Secret Labs AB "; #include "Python.h" -#include "pycore_dict.h" // _PyDict_Next() -#include "pycore_long.h" // _PyLong_GetZero() -#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION +#include "pycore_dict.h" // _PyDict_Next() +#include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_moduleobject.h" // _PyModule_GetState() -#include "sre.h" // SRE_CODE +#include "sre.h" // SRE_CODE -#include <ctype.h> // tolower(), toupper(), isalnum() +#include <ctype.h> // tolower(), toupper(), isalnum() #define SRE_CODE_BITS (8 * sizeof(SRE_CODE)) @@ -2349,26 +2350,28 @@ _sre_SRE_Match_groupdict_impl(MatchObject *self, PyObject *default_value) if (!result || !self->pattern->groupindex) return result; + Py_BEGIN_CRITICAL_SECTION(self->pattern->groupindex); while (_PyDict_Next(self->pattern->groupindex, &pos, &key, &value, &hash)) { int status; Py_INCREF(key); value = match_getslice(self, key, default_value); if (!value) { Py_DECREF(key); - goto failed; + Py_CLEAR(result); + goto exit; } status = _PyDict_SetItem_KnownHash(result, key, value, hash); Py_DECREF(value); Py_DECREF(key); - if (status < 0) - goto failed; + if (status < 0) { + Py_CLEAR(result); + goto exit; + } } +exit: + Py_END_CRITICAL_SECTION(); return result; - -failed: - Py_DECREF(result); - return NULL; } /*[clinic input] |