Skip to content

Commit fcdcf7f

Browse files
committed
Allow multiple calls to loop.stop
Calling loop.stop and then immediately proceeding to exit the `open_loop`'s context (without hitting any checkpoints) causes the program to hang forever Fix by reusing the same `waiter` event across multiple calls to `stop` Fixes python-trio#58
1 parent 8098e93 commit fcdcf7f

File tree

3 files changed

+14
-1
lines changed

3 files changed

+14
-1
lines changed

tests/test_misc.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ def close_no_stop():
2626
await trio.sleep(0.1)
2727
await loop.wait_closed()
2828

29+
@pytest.mark.trio
30+
async def test_too_many_stops(self):
31+
with trio.move_on_after(1) as scope:
32+
async with trio_asyncio.open_loop() as loop:
33+
await trio.hazmat.checkpoint()
34+
loop.stop()
35+
assert not scope.cancelled_caught, \
36+
"Possible deadlock after manual call to loop.stop"
37+
2938
@pytest.mark.trio
3039
async def test_err1(self, loop):
3140
async def raise_err():

trio_asyncio/async_.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ def stop(self, waiter=None):
6060
6161
"""
6262
if waiter is None:
63-
waiter = trio.Event()
63+
if self._stop_wait is not None:
64+
return self._stop_wait
65+
waiter = self._stop_wait = trio.Event()
6466
else:
6567
waiter.clear()
6668

trio_asyncio/base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ def __init__(self, queue_len=None):
172172
self._stopped = trio.Event()
173173
self._stopped.set()
174174

175+
self._stop_wait = None
176+
175177
def __repr__(self):
176178
try:
177179
return "<%s running=%s at 0x%x>" % (

0 commit comments

Comments
 (0)