New submission from David Coles: If a task that is waiting on an asyncio.Condition is cancelled after notification but before having successfully reacquired the associated lock, the acquire() will be cancelled causing wait() to return without the lock held (violating wait()'s contract and leaving the program in an inconsistent state).
This can be reproduced in cases where there's some contention on the Condition's lock. For example: import asyncio loop = asyncio.get_event_loop() cond = asyncio.Condition() @asyncio.coroutine def cond_wait_timeout(condition, timeout): wait_task = asyncio.async(condition.wait()) loop.call_later(timeout, wait_task.cancel) try: yield from wait_task return True except asyncio.CancelledError: print("Timeout (locked: {0})".format(condition.locked())) return False @asyncio.coroutine def waiter(): yield from cond.acquire() try: print("Wait") if (yield from cond_wait_timeout(cond, 1)): # Cause some lock contention print("Do work") yield from asyncio.sleep(1) finally: cond.release() @asyncio.coroutine def notifier(): # Yield to the waiters yield from asyncio.sleep(0.1) yield from cond.acquire() try: print("Notify") cond.notify_all() finally: cond.release() loop.run_until_complete(asyncio.wait([waiter(), waiter(), notifier()])) The most straightforward fix appears to be just to have wait() retry to acquire the lock, effectively ignoring cancellation at this point (since the condition has already finished waiting and just trying to reacquire the lock before returning). ---------- components: asyncio files: asyncio-fix-wait-cancellation-race.patch keywords: patch messages: 231912 nosy: dcoles, gvanrossum, haypo, yselivanov priority: normal severity: normal status: open title: Cancelling wait() after notification leaves Condition in an inconsistent state type: behavior versions: Python 3.4 Added file: http://bugs.python.org/file37330/asyncio-fix-wait-cancellation-race.patch _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue22970> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com