Skip to content

Commit

Permalink
pythongh-127521: Mark list as "shared" before resizing if necessary (p…
Browse files Browse the repository at this point in the history
…ythonGH-127524)

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 c7dec02)

Co-authored-by: Sam Gross <[email protected]>
  • Loading branch information
colesbury authored and miss-islington committed Dec 2, 2024
1 parent 219b826 commit e46b077
Showing 1 changed file with 20 additions and 0 deletions.
20 changes: 20 additions & 0 deletions Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit e46b077

Please sign in to comment.