This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author dcoles
Recipients dcoles, gvanrossum, vstinner, yselivanov
Date 2014-12-01.03:29:39
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1417404582.01.0.276361050449.issue22970@psf.upfronthosting.co.za>
In-reply-to
Content
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).
History
Date User Action Args
2014-12-01 03:29:42dcolessetrecipients: + dcoles, gvanrossum, vstinner, yselivanov
2014-12-01 03:29:42dcolessetmessageid: <1417404582.01.0.276361050449.issue22970@psf.upfronthosting.co.za>
2014-12-01 03:29:41dcoleslinkissue22970 messages
2014-12-01 03:29:40dcolescreate