Kaydet (Commit) d35bf032 authored tarafından Yury Selivanov's avatar Yury Selivanov

Merge 3.5 (issue #22970)

...@@ -329,7 +329,13 @@ class Condition(_ContextManagerMixin): ...@@ -329,7 +329,13 @@ class Condition(_ContextManagerMixin):
self._waiters.remove(fut) self._waiters.remove(fut)
finally: finally:
yield from self.acquire() # Must reacquire lock even if wait is cancelled
while True:
try:
yield from self.acquire()
break
except futures.CancelledError:
pass
@coroutine @coroutine
def wait_for(self, predicate): def wait_for(self, predicate):
......
...@@ -457,6 +457,31 @@ class ConditionTests(test_utils.TestCase): ...@@ -457,6 +457,31 @@ class ConditionTests(test_utils.TestCase):
self.assertFalse(cond._waiters) self.assertFalse(cond._waiters)
self.assertTrue(cond.locked()) self.assertTrue(cond.locked())
def test_wait_cancel_contested(self):
cond = asyncio.Condition(loop=self.loop)
self.loop.run_until_complete(cond.acquire())
self.assertTrue(cond.locked())
wait_task = asyncio.Task(cond.wait(), loop=self.loop)
test_utils.run_briefly(self.loop)
self.assertFalse(cond.locked())
# Notify, but contest the lock before cancelling
self.loop.run_until_complete(cond.acquire())
self.assertTrue(cond.locked())
cond.notify()
self.loop.call_soon(wait_task.cancel)
self.loop.call_soon(cond.release)
try:
self.loop.run_until_complete(wait_task)
except asyncio.CancelledError:
# Should not happen, since no cancellation points
pass
self.assertTrue(cond.locked())
def test_wait_unacquired(self): def test_wait_unacquired(self):
cond = asyncio.Condition(loop=self.loop) cond = asyncio.Condition(loop=self.loop)
self.assertRaises( self.assertRaises(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment