Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1e67b92

Browse files
authored
gh-117657: Fix TSAN list set failure (#118260)
* Fix TSAN list set failure* Relaxed atomic is sufficient, add targetted test* More list* Remove atomic assign in list* Fixup white space
1 parent8ed5466 commit1e67b92

File tree

3 files changed

+90
-3
lines changed

3 files changed

+90
-3
lines changed

‎Include/internal/pycore_list.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ _PyList_AppendTakeRef(PyListObject *self, PyObject *newitem)
2828
Py_ssize_tallocated=self->allocated;
2929
assert((size_t)len+1<PY_SSIZE_T_MAX);
3030
if (allocated>len) {
31+
#ifdefPy_GIL_DISABLED
32+
_Py_atomic_store_ptr_release(&self->ob_item[len],newitem);
33+
#else
3134
PyList_SET_ITEM(self,len,newitem);
35+
#endif
3236
Py_SET_SIZE(self,len+1);
3337
return0;
3438
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
importunittest
2+
3+
fromthreadingimportThread
4+
fromunittestimportTestCase
5+
6+
fromtest.supportimportis_wasi
7+
8+
9+
classC:
10+
def__init__(self,v):
11+
self.v=v
12+
13+
14+
@unittest.skipIf(is_wasi,"WASI has no threads.")
15+
classTestList(TestCase):
16+
deftest_racing_iter_append(self):
17+
18+
l= []
19+
OBJECT_COUNT=10000
20+
21+
defwriter_func():
22+
foriinrange(OBJECT_COUNT):
23+
l.append(C(i+OBJECT_COUNT))
24+
25+
defreader_func():
26+
whileTrue:
27+
count=len(l)
28+
fori,xinenumerate(l):
29+
self.assertEqual(x.v,i+OBJECT_COUNT)
30+
ifcount==OBJECT_COUNT:
31+
break
32+
33+
writer=Thread(target=writer_func)
34+
readers= []
35+
forxinrange(30):
36+
reader=Thread(target=reader_func)
37+
readers.append(reader)
38+
reader.start()
39+
40+
writer.start()
41+
writer.join()
42+
forreaderinreaders:
43+
reader.join()
44+
45+
deftest_racing_iter_extend(self):
46+
iters= [
47+
lambdax: [x],
48+
]
49+
foriter_caseiniters:
50+
withself.subTest(iter=iter_case):
51+
l= []
52+
OBJECT_COUNT=10000
53+
54+
defwriter_func():
55+
foriinrange(OBJECT_COUNT):
56+
l.extend(iter_case(C(i+OBJECT_COUNT)))
57+
58+
defreader_func():
59+
whileTrue:
60+
count=len(l)
61+
fori,xinenumerate(l):
62+
self.assertEqual(x.v,i+OBJECT_COUNT)
63+
ifcount==OBJECT_COUNT:
64+
break
65+
66+
writer=Thread(target=writer_func)
67+
readers= []
68+
forxinrange(30):
69+
reader=Thread(target=reader_func)
70+
readers.append(reader)
71+
reader.start()
72+
73+
writer.start()
74+
writer.join()
75+
forreaderinreaders:
76+
reader.join()
77+
78+
79+
if__name__=="__main__":
80+
unittest.main()

‎Objects/listobject.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ list_resize(PyListObject *self, Py_ssize_t newsize)
141141
target_bytes=allocated*sizeof(PyObject*);
142142
}
143143
memcpy(array->ob_item,self->ob_item,target_bytes);
144+
}
145+
if (new_allocated> (size_t)allocated) {
146+
memset(array->ob_item+allocated,0,sizeof(PyObject*)* (new_allocated-allocated));
144147
}
145148
_Py_atomic_store_ptr_release(&self->ob_item,&array->ob_item);
146149
self->allocated=new_allocated;
@@ -502,7 +505,7 @@ _PyList_AppendTakeRefListResize(PyListObject *self, PyObject *newitem)
502505
Py_DECREF(newitem);
503506
return-1;
504507
}
505-
PyList_SET_ITEM(self,len,newitem);
508+
FT_ATOMIC_STORE_PTR_RELEASE(self->ob_item[len],newitem);
506509
return0;
507510
}
508511

@@ -1181,7 +1184,7 @@ list_extend_fast(PyListObject *self, PyObject *iterable)
11811184
PyObject**dest=self->ob_item+m;
11821185
for (Py_ssize_ti=0;i<n;i++) {
11831186
PyObject*o=src[i];
1184-
dest[i]=Py_NewRef(o);
1187+
FT_ATOMIC_STORE_PTR_RELEASE(dest[i],Py_NewRef(o));
11851188
}
11861189
return0;
11871190
}
@@ -1238,7 +1241,7 @@ list_extend_iter_lock_held(PyListObject *self, PyObject *iterable)
12381241

12391242
if (Py_SIZE(self)<self->allocated) {
12401243
Py_ssize_tlen=Py_SIZE(self);
1241-
PyList_SET_ITEM(self,len,item);// steals item ref
1244+
FT_ATOMIC_STORE_PTR_RELEASE(self->ob_item[len],item);// steals item ref
12421245
Py_SET_SIZE(self,len+1);
12431246
}
12441247
else {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp