https://github.com/python/cpython/commit/e546876d83e1cc3f761e1eeca57f8a4533d06d00
commit: e546876d83e1cc3f761e1eeca57f8a4533d06d00
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: colesbury <[email protected]>
date: 2024-12-02T19:22:05-05:00
summary:

[3.13] gh-127521: Mark list as "shared" before resizing if necessary 
(GH-127524) (GH-127533)

In the free threading build, if a non-owning thread resizes a list,
it must use QSBR to free the old list array because there may be a
concurrent access (without a lock) from the owning thread.

To match the pattern in dictobject.c, we just mark the list as "shared"
before resizing if it's from a non-owning thread and not already marked
as shared.
(cherry picked from commit c7dec02de2ed4baf3cd22ad094350265b52c18af)

Co-authored-by: Sam Gross <[email protected]>

files:
M Objects/listobject.c

diff --git a/Objects/listobject.c b/Objects/listobject.c
index dc9df3c3614fb4..89abbda155a8b6 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -77,6 +77,20 @@ free_list_items(PyObject** items, bool use_qsbr)
 #endif
 }
 
+static void
+ensure_shared_on_resize(PyListObject *self)
+{
+#ifdef Py_GIL_DISABLED
+    // Ensure that the list array is freed using QSBR if we are not the
+    // owning thread.
+    if (!_Py_IsOwnedByCurrentThread((PyObject *)self) &&
+        !_PyObject_GC_IS_SHARED(self))
+    {
+        _PyObject_GC_SET_SHARED(self);
+    }
+#endif
+}
+
 /* Ensure ob_item has room for at least newsize elements, and set
  * ob_size to newsize.  If newsize > ob_size on entry, the content
  * of the new slots at exit is undefined heap trash; it's the caller's
@@ -126,6 +140,8 @@ list_resize(PyListObject *self, Py_ssize_t newsize)
     if (newsize == 0)
         new_allocated = 0;
 
+    ensure_shared_on_resize(self);
+
 #ifdef Py_GIL_DISABLED
     _PyListArray *array = list_allocate_array(new_allocated);
     if (array == NULL) {
@@ -842,6 +858,9 @@ list_clear_impl(PyListObject *a, bool is_resize)
         Py_XDECREF(items[i]);
     }
 #ifdef Py_GIL_DISABLED
+    if (is_resize) {
+        ensure_shared_on_resize(a);
+    }
     bool use_qsbr = is_resize && _PyObject_GC_IS_SHARED(a);
 #else
     bool use_qsbr = false;
@@ -3107,6 +3126,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int 
reverse)
             Py_XDECREF(final_ob_item[i]);
         }
 #ifdef Py_GIL_DISABLED
+        ensure_shared_on_resize(self);
         bool use_qsbr = _PyObject_GC_IS_SHARED(self);
 #else
         bool use_qsbr = false;

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to