mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-130920: Fix data race in STORE_SUBSCR_LIST_INT (#130923)
The write of the item to the list needs to use an atomic operation in the free threading build. Co-authored-by: Tomasz Pytel <tompytel@gmail.com>
This commit is contained in:
parent
6c6600f683
commit
a025f27d94
4 changed files with 21 additions and 4 deletions
|
@ -1,6 +1,6 @@
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from threading import Thread
|
from threading import Thread, Barrier
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
from test.support import threading_helper
|
from test.support import threading_helper
|
||||||
|
@ -71,6 +71,20 @@ class TestList(TestCase):
|
||||||
for reader in readers:
|
for reader in readers:
|
||||||
reader.join()
|
reader.join()
|
||||||
|
|
||||||
|
def test_store_list_int(self):
|
||||||
|
def copy_back_and_forth(b, l):
|
||||||
|
b.wait()
|
||||||
|
for _ in range(100):
|
||||||
|
l[0] = l[1]
|
||||||
|
l[1] = l[0]
|
||||||
|
|
||||||
|
l = [0, 1]
|
||||||
|
barrier = Barrier(NTHREAD)
|
||||||
|
threads = [Thread(target=copy_back_and_forth, args=(barrier, l))
|
||||||
|
for _ in range(NTHREAD)]
|
||||||
|
with threading_helper.start_threads(threads):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -1015,7 +1015,8 @@ dummy_func(
|
||||||
STAT_INC(STORE_SUBSCR, hit);
|
STAT_INC(STORE_SUBSCR, hit);
|
||||||
|
|
||||||
PyObject *old_value = PyList_GET_ITEM(list, index);
|
PyObject *old_value = PyList_GET_ITEM(list, index);
|
||||||
PyList_SET_ITEM(list, index, PyStackRef_AsPyObjectSteal(value));
|
FT_ATOMIC_STORE_PTR_RELEASE(_PyList_ITEMS(list)[index],
|
||||||
|
PyStackRef_AsPyObjectSteal(value));
|
||||||
assert(old_value != NULL);
|
assert(old_value != NULL);
|
||||||
UNLOCK_OBJECT(list); // unlock before decrefs!
|
UNLOCK_OBJECT(list); // unlock before decrefs!
|
||||||
PyStackRef_CLOSE_SPECIALIZED(sub_st, _PyLong_ExactDealloc);
|
PyStackRef_CLOSE_SPECIALIZED(sub_st, _PyLong_ExactDealloc);
|
||||||
|
|
3
Python/executor_cases.c.h
generated
3
Python/executor_cases.c.h
generated
|
@ -1522,7 +1522,8 @@
|
||||||
}
|
}
|
||||||
STAT_INC(STORE_SUBSCR, hit);
|
STAT_INC(STORE_SUBSCR, hit);
|
||||||
PyObject *old_value = PyList_GET_ITEM(list, index);
|
PyObject *old_value = PyList_GET_ITEM(list, index);
|
||||||
PyList_SET_ITEM(list, index, PyStackRef_AsPyObjectSteal(value));
|
FT_ATOMIC_STORE_PTR_RELEASE(_PyList_ITEMS(list)[index],
|
||||||
|
PyStackRef_AsPyObjectSteal(value));
|
||||||
assert(old_value != NULL);
|
assert(old_value != NULL);
|
||||||
UNLOCK_OBJECT(list); // unlock before decrefs!
|
UNLOCK_OBJECT(list); // unlock before decrefs!
|
||||||
PyStackRef_CLOSE_SPECIALIZED(sub_st, _PyLong_ExactDealloc);
|
PyStackRef_CLOSE_SPECIALIZED(sub_st, _PyLong_ExactDealloc);
|
||||||
|
|
3
Python/generated_cases.c.h
generated
3
Python/generated_cases.c.h
generated
|
@ -11259,7 +11259,8 @@
|
||||||
}
|
}
|
||||||
STAT_INC(STORE_SUBSCR, hit);
|
STAT_INC(STORE_SUBSCR, hit);
|
||||||
PyObject *old_value = PyList_GET_ITEM(list, index);
|
PyObject *old_value = PyList_GET_ITEM(list, index);
|
||||||
PyList_SET_ITEM(list, index, PyStackRef_AsPyObjectSteal(value));
|
FT_ATOMIC_STORE_PTR_RELEASE(_PyList_ITEMS(list)[index],
|
||||||
|
PyStackRef_AsPyObjectSteal(value));
|
||||||
assert(old_value != NULL);
|
assert(old_value != NULL);
|
||||||
UNLOCK_OBJECT(list); // unlock before decrefs!
|
UNLOCK_OBJECT(list); // unlock before decrefs!
|
||||||
PyStackRef_CLOSE_SPECIALIZED(sub_st, _PyLong_ExactDealloc);
|
PyStackRef_CLOSE_SPECIALIZED(sub_st, _PyLong_ExactDealloc);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue