mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
Issue #22970: asyncio: Fix inconsistency cancelling Condition.wait.
Patch by David Coles.
This commit is contained in:
parent
ca2e0a48cf
commit
c92bf83a82
3 changed files with 35 additions and 1 deletions
|
@ -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):
|
||||||
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(
|
||||||
|
|
|
@ -524,6 +524,9 @@ Library
|
||||||
_conn_lost.
|
_conn_lost.
|
||||||
Patch by Łukasz Langa.
|
Patch by Łukasz Langa.
|
||||||
|
|
||||||
|
- Issue #22970: asyncio: Fix inconsistency cancelling Condition.wait.
|
||||||
|
Patch by David Coles.
|
||||||
|
|
||||||
IDLE
|
IDLE
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue