bpo-30064: Fix asyncio loop.sock_* race condition issue by fantix · Pull Request #20369 · python/cpython
https://bugs.python.org/issue30064
This is reproducible by a cancel() followed directly by a retry:
done, pending = await asyncio.wait([loop.sock_recv(sock, 1024)], timeout=0.1) if done: data = await done.pop() else: pending.pop().cancel() data = await loop.sock_recv(sock, 1024)
This issue applies to all the loop.sock_* methods. Without this PR, users could work it around by adding a sleep(0):
done, pending = await asyncio.wait([loop.sock_recv(sock, 1024)], timeout=0.1) if done: data = await done.pop() else: pending.pop().cancel() await asyncio.sleep(0) # <---- this ensures that the right reader is removed data = await loop.sock_recv(sock, 1024)