]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-112087: Make list.sort to be thread-safe for PEP 703. (gh-116553)
authorDonghee Na <donghee.na@python.org>
Sun, 10 Mar 2024 00:45:42 +0000 (09:45 +0900)
committerGitHub <noreply@github.com>
Sun, 10 Mar 2024 00:45:42 +0000 (00:45 +0000)
Objects/clinic/listobject.c.h
Objects/listobject.c

index a61550a49b66fc8568fc58a97210a041e598fbae..b90dc0a0b463c638aa78b80944a1b2c5af97daae 100644 (file)
@@ -268,7 +268,9 @@ list_sort(PyListObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject
         goto exit;
     }
 skip_optional_kwonly:
+    Py_BEGIN_CRITICAL_SECTION(self);
     return_value = list_sort_impl(self, keyfunc, reverse);
+    Py_END_CRITICAL_SECTION();
 
 exit:
     return return_value;
@@ -452,4 +454,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored))
 {
     return list___reversed___impl(self);
 }
-/*[clinic end generated code: output=26dfb2c9846348f9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=a77eda9931ec0c20 input=a9049054013a1b77]*/
index c2aaab0ec3b4155883a25dc4a4e5fbbb574b1b9a..164f363efe24f05440b867ae20c835d7023475d1 100644 (file)
@@ -2577,6 +2577,7 @@ unsafe_tuple_compare(PyObject *v, PyObject *w, MergeState *ms)
  * duplicated).
  */
 /*[clinic input]
+@critical_section
 list.sort
 
     *
@@ -2596,7 +2597,7 @@ The reverse flag can be set to sort in descending order.
 
 static PyObject *
 list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
-/*[clinic end generated code: output=57b9f9c5e23fbe42 input=a74c4cd3ec6b5c08]*/
+/*[clinic end generated code: output=57b9f9c5e23fbe42 input=667bf25d0e3a3676]*/
 {
     MergeState ms;
     Py_ssize_t nremaining;
@@ -2623,7 +2624,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
     saved_ob_item = self->ob_item;
     saved_allocated = self->allocated;
     Py_SET_SIZE(self, 0);
-    self->ob_item = NULL;
+    FT_ATOMIC_STORE_PTR_RELEASE(self->ob_item, NULL);
     self->allocated = -1; /* any operation will reset it to >= 0 */
 
     if (keyfunc == NULL) {
@@ -2843,8 +2844,8 @@ keyfunc_fail:
     final_ob_item = self->ob_item;
     i = Py_SIZE(self);
     Py_SET_SIZE(self, saved_ob_size);
-    self->ob_item = saved_ob_item;
-    self->allocated = saved_allocated;
+    FT_ATOMIC_STORE_PTR_RELEASE(self->ob_item, saved_ob_item);
+    FT_ATOMIC_STORE_SSIZE_RELAXED(self->allocated, saved_allocated);
     if (final_ob_item != NULL) {
         /* we cannot use list_clear() for this because it does not
            guarantee that the list is really empty when it returns */
@@ -2870,7 +2871,9 @@ PyList_Sort(PyObject *v)
         PyErr_BadInternalCall();
         return -1;
     }
+    Py_BEGIN_CRITICAL_SECTION(v);
     v = list_sort_impl((PyListObject *)v, NULL, 0);
+    Py_END_CRITICAL_SECTION();
     if (v == NULL)
         return -1;
     Py_DECREF(v);