gh-140476: optimize PySet_Add for frozenset in free-threading (#140440)
Avoids critical section in `PySet_Add` when adding items to newly created frozensets. Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
@@ -2775,17 +2775,24 @@ PySet_Discard(PyObject *set, PyObject *key)
|
||||
int
|
||||
PySet_Add(PyObject *anyset, PyObject *key)
|
||||
{
|
||||
if (!PySet_Check(anyset) &&
|
||||
(!PyFrozenSet_Check(anyset) || !_PyObject_IsUniquelyReferenced(anyset))) {
|
||||
PyErr_BadInternalCall();
|
||||
return -1;
|
||||
if (PySet_Check(anyset)) {
|
||||
int rv;
|
||||
Py_BEGIN_CRITICAL_SECTION(anyset);
|
||||
rv = set_add_key((PySetObject *)anyset, key);
|
||||
Py_END_CRITICAL_SECTION();
|
||||
return rv;
|
||||
}
|
||||
|
||||
int rv;
|
||||
Py_BEGIN_CRITICAL_SECTION(anyset);
|
||||
rv = set_add_key((PySetObject *)anyset, key);
|
||||
Py_END_CRITICAL_SECTION();
|
||||
return rv;
|
||||
if (PyFrozenSet_Check(anyset) && _PyObject_IsUniquelyReferenced(anyset)) {
|
||||
// We can only change frozensets if they are uniquely referenced. The
|
||||
// API limits the usage of `PySet_Add` to "fill in the values of brand
|
||||
// new frozensets before they are exposed to other code". In this case,
|
||||
// this can be done without a lock.
|
||||
return set_add_key((PySetObject *)anyset, key);
|
||||
}
|
||||
|
||||
PyErr_BadInternalCall();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
Reference in New Issue
Block a user