Skip to content

Commit 2da4678

Browse files
committed
Add more to the test.
1 parent 192b6a3 commit 2da4678

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

Lib/test/test_free_threading/test_generators.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,48 @@
22

33
from unittest import TestCase
44

5+
from test import support
56
from test.support import threading_helper
7+
from threading import Thread
68

79
@threading_helper.requires_working_threading()
10+
@support.requires_resource("cpu")
811
class TestGen(TestCase):
9-
def test_generator_send(self):
10-
import threading
11-
12+
def infinite_generator(self):
1213
def gen():
13-
for _ in range(5_000):
14+
while True:
1415
yield
1516

17+
return gen()
18+
19+
def stress_generator(self, *funcs):
20+
threads = []
21+
gen = self.infinite_generator()
22+
23+
for func in funcs:
24+
for _ in range(10):
25+
def with_iterations(gen):
26+
for _ in range(100):
27+
func(gen)
1628

17-
it = gen()
18-
with threading_helper.catch_threading_exception() as cm:
19-
# next(it) is equivalent to it.send(None)
20-
with threading_helper.start_threads(
21-
(threading.Thread(target=lambda: next(it)) for _ in range(10))
22-
):
23-
pass
29+
threads.append(Thread(target=with_iterations, args=(gen,)))
30+
31+
for thread in threads:
32+
thread.start()
33+
34+
for thread in threads:
35+
thread.join()
36+
37+
def test_generator_send(self):
38+
self.stress_generator(lambda gen: next(gen))
2439

25-
self.assertIsNone(cm.exc_value)
40+
def test_generator_close(self):
41+
self.stress_generator(lambda gen: gen.close())
42+
self.stress_generator(lambda gen: next(gen), lambda gen: gen.close())
2643

44+
def test_generator_state(self):
45+
self.stress_generator(lambda gen: next(gen), lambda gen: gen.gi_running)
46+
self.stress_generator(lambda gen: gen.gi_isrunning, lambda gen: gen.close())
2747

2848
if __name__ == "__main__":
2949
unittest.main()

Python/ceval.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,7 @@ clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame)
17411741
{
17421742
assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
17431743
PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
1744+
Py_BEGIN_CRITICAL_SECTION(gen);
17441745
gen->gi_frame_state = FRAME_CLEARED;
17451746
assert(tstate->exc_info == &gen->gi_exc_state);
17461747
tstate->exc_info = gen->gi_exc_state.previous_item;
@@ -1751,6 +1752,7 @@ clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame)
17511752
_PyErr_ClearExcState(&gen->gi_exc_state);
17521753
tstate->c_recursion_remaining++;
17531754
frame->previous = NULL;
1755+
Py_END_CRITICAL_SECTION();
17541756
}
17551757

17561758
void

0 commit comments

Comments
 (0)