Skip to content

asyncio.Server.wait_closed() appears to hang indefinitely in 3.12.0a7#104344

@jnsnow

Description

@jnsnow

Bug report

I have some code in the qemu.qmp package that appears to work correctly in Python 3.6 (RIP~) through to Python 3.11. I've started testing against 3.12 and I'm finding that waiting on asyncio.Server.wait_closed() is creating a deadlock/hang.

Here's a minimal-ish reproducer:

#!/usr/bin/env python3importasyncioasyncdefcause_problems(): accepted=asyncio.Event() asyncdef_incoming(reader, writer): print("entered _incoming") print("signaling outer context; we accepted a client") accepted.set() print("left _incoming") print("starting server") server=awaitasyncio.start_unix_server( _incoming, path="problems.sock", backlog=1, ) print("created server; waiting on a client") awaitaccepted.wait() print("got a client") print("closing server") server.close() print("issued close()") awaitserver.wait_closed() print("finished waiting on server to close") if__name__=='__main__': asyncio.run(cause_problems())

You can test a simple connection using whatever you'd like; socat works to trigger the accept code, e.g. from the same directory that you run the above code, try:

socat UNIX-CONNECT:problems.sock stdout

Here's what happens in python 3.11.3

jsnow@scv ~> python3.11 hang.py starting server created server; waiting on a client entered _incoming signaling outer context; we accepted a client left _incoming got a client closing server issued close() finished waiting on server to close 

And here's 3.12.0a7:

jsnow@scv ~> python3.12 hang.py starting server created server; waiting on a client entered _incoming signaling outer context; we accepted a client left _incoming got a client closing server issued close() 

When I issue ^C, we get this traceback:

^CTraceback (most recent call last): File "/usr/lib64/python3.12/asyncio/runners.py", line 118, in run return self._loop.run_until_complete(task) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.12/asyncio/base_events.py", line 664, in run_until_complete return future.result() ^^^^^^^^^^^^^^^ File "/home/jsnow/hang2.py", line 26, in cause_problems await server.wait_closed() File "/usr/lib64/python3.12/asyncio/base_events.py", line 384, in wait_closed await waiter asyncio.exceptions.CancelledError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/jsnow/hang2.py", line 31, in <module> asyncio.run(cause_problems()) File "/usr/lib64/python3.12/asyncio/runners.py", line 194, in run return runner.run(main) ^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.12/asyncio/runners.py", line 123, in run raise KeyboardInterrupt() KeyboardInterrupt 

Your environment

  • Python 3.12.0a7 (as packaged on Fedora 37)
  • Linux 6.2.12-200.fc37.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Apr 20 23:38:29 UTC 2023
  • Tested on CPython 3.6 through 3.12 as available on Fedora 37. Works on 3.6, 3.7, 3.8, 3.9, 3.10 and 3.11 but fails on the 3.12 alpha package.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions