python-trio / trio-asyncio

a re-implementation of the asyncio mainloop on top of Trio

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Intermittent deadlock in test_misc.test_cancel_sleep (macOS only?)

shamrin opened this issue · comments

Observation

I managed to replicate the deadlock on my Mac, but running the following in 6 console windows, simultaneously. It takes a few minutes to get to a deadlock:

while true; do pytest tests/test_misc.py; done

(By the way, Ctrl-C does nothing.)

We have seen the deadlock in GitHub Actions as well:

...
2021-01-07T13:36:00.2183290Z ../tests/test_misc.py::TestMisc::test_err2 PASSED                        [  2%]
2021-01-07T13:36:00.2328220Z ../tests/test_misc.py::TestMisc::test_run3 PASSED                        [  2%]
2021-01-07T13:45:34.4670010Z ##[error]The operation was canceled.
...

https://github.com/python-trio/trio-asyncio/runs/1662700976

Analysis

It deadlocks because of combination of two things:

  1. in test_cancel_sleep the do_no_run callback sometimes runs h.cancel() (timer inaccuracy?)
  2. raise Exceptions("should not run") triggers wait_task_rescheduled abort_cb callback in run_aio_future and the task never gets scheduled again.

async def test_cancel_sleep(self, loop):
owch = 0
def do_not_run():
nonlocal owch
owch = 1
raise Exception("should not run")
async def cancel_sleep():
h = loop.call_later(0.2, do_not_run)
await asyncio.sleep(0.1, loop=loop)
h.cancel()
await asyncio.sleep(0.3, loop=loop)
await trio_asyncio.aio_as_trio(cancel_sleep, loop=loop)()
assert owch == 0