Skip to content

Commit a7df3c2

Browse files
committed
gh-129824: Fix data races in type_ready with subinterpreters
Also add test_interpreters to the list of TSAN tests. The test_running and test_is_running test cases are skipped for now as they have file descriptor races.
1 parent 7b2e01b commit a7df3c2

File tree

3 files changed

+21
-3
lines changed

3 files changed

+21
-3
lines changed

Lib/test/libregrtest/tsan.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
'test_httpservers',
1212
'test_imaplib',
1313
'test_importlib',
14+
'test_interpreters',
1415
'test_io',
1516
'test_logging',
1617
'test_queue',

Lib/test/test_interpreters/test_api.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,7 @@ def test_not_shareable(self):
703703
with self.assertRaises(ExecutionFailed):
704704
interp.exec('print(spam)')
705705

706+
@support.skip_if_sanitizer('gh-129824: file descriptor race', thread=True)
706707
def test_running(self):
707708
interp = interpreters.create()
708709
interp.prepare_main({'spam': True})
@@ -1530,6 +1531,7 @@ def test_whence(self):
15301531
whence = eval(text)
15311532
self.assertEqual(whence, _interpreters.WHENCE_LEGACY_CAPI)
15321533

1534+
@support.skip_if_sanitizer('gh-129824: file descriptor race', thread=True)
15331535
def test_is_running(self):
15341536
def check(interpid, expected):
15351537
with self.assertRaisesRegex(InterpreterError, 'unrecognized'):

Objects/typeobject.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8506,7 +8506,12 @@ type_ready_set_new(PyTypeObject *type, int initial)
85068506
&& base == &PyBaseObject_Type
85078507
&& !(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
85088508
{
8509-
type->tp_flags |= Py_TPFLAGS_DISALLOW_INSTANTIATION;
8509+
if (initial) {
8510+
type->tp_flags |= Py_TPFLAGS_DISALLOW_INSTANTIATION;
8511+
}
8512+
else {
8513+
assert(_PyType_HasFeature(type, Py_TPFLAGS_DISALLOW_INSTANTIATION));
8514+
}
85108515
}
85118516

85128517
if (!(type->tp_flags & Py_TPFLAGS_DISALLOW_INSTANTIATION)) {
@@ -8526,7 +8531,12 @@ type_ready_set_new(PyTypeObject *type, int initial)
85268531
}
85278532
else {
85288533
// Py_TPFLAGS_DISALLOW_INSTANTIATION sets tp_new to NULL
8529-
type->tp_new = NULL;
8534+
if (initial) {
8535+
type->tp_new = NULL;
8536+
}
8537+
else {
8538+
assert(type->tp_new == NULL);
8539+
}
85308540
}
85318541
return 0;
85328542
}
@@ -8659,7 +8669,12 @@ type_ready(PyTypeObject *type, int initial)
86598669
}
86608670

86618671
/* All done -- set the ready flag */
8662-
type->tp_flags |= Py_TPFLAGS_READY;
8672+
if (initial) {
8673+
type->tp_flags |= Py_TPFLAGS_READY;
8674+
}
8675+
else {
8676+
assert(_PyType_HasFeature(type, Py_TPFLAGS_READY));
8677+
}
86638678
stop_readying(type);
86648679

86658680
assert(_PyType_CheckConsistency(type));

0 commit comments

Comments
 (0)