summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2015-09-29 18:54:45 (GMT)
committerGuido van Rossum <guido@python.org>2015-09-29 18:54:45 (GMT)
commitd455a50773eb1f4531882a0b99ff7a253ad1d41e (patch)
tree28211b4643e499edddd219416ba19a5a93cfa5d0 /Lib/asyncio
parentd94c1b92ed6420044d38b59371fd934b9ca9a79f (diff)
downloadcpython-d455a50773eb1f4531882a0b99ff7a253ad1d41e.zip
cpython-d455a50773eb1f4531882a0b99ff7a253ad1d41e.tar.gz
cpython-d455a50773eb1f4531882a0b99ff7a253ad1d41e.tar.bz2
Also rewrote the guts of asyncio.Semaphore (patch by manipopopo).
Diffstat (limited to 'Lib/asyncio')
-rw-r--r--Lib/asyncio/locks.py37
1 files changed, 21 insertions, 16 deletions
diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py
index 7a13279..34f6bc1 100644
--- a/Lib/asyncio/locks.py
+++ b/Lib/asyncio/locks.py
@@ -411,6 +411,13 @@ class Semaphore(_ContextManagerMixin):
extra = '{},waiters:{}'.format(extra, len(self._waiters))
return '<{} [{}]>'.format(res[1:-1], extra)
+ def _wake_up_next(self):
+ while self._waiters:
+ waiter = self._waiters.popleft()
+ if not waiter.done():
+ waiter.set_result(None)
+ return
+
def locked(self):
"""Returns True if semaphore can not be acquired immediately."""
return self._value == 0
@@ -425,18 +432,19 @@ class Semaphore(_ContextManagerMixin):
called release() to make it larger than 0, and then return
True.
"""
- if not self._waiters and self._value > 0:
- self._value -= 1
- return True
-
- fut = futures.Future(loop=self._loop)
- self._waiters.append(fut)
- try:
- yield from fut
- self._value -= 1
- return True
- finally:
- self._waiters.remove(fut)
+ while self._value <= 0:
+ fut = futures.Future(loop=self._loop)
+ self._waiters.append(fut)
+ try:
+ yield from fut
+ except:
+ # See the similar code in Queue.get.
+ fut.cancel()
+ if self._value > 0 and not fut.cancelled():
+ self._wake_up_next()
+ raise
+ self._value -= 1
+ return True
def release(self):
"""Release a semaphore, incrementing the internal counter by one.
@@ -444,10 +452,7 @@ class Semaphore(_ContextManagerMixin):
become larger than zero again, wake up that coroutine.
"""
self._value += 1
- for waiter in self._waiters:
- if not waiter.done():
- waiter.set_result(True)
- break
+ self._wake_up_next()
class BoundedSemaphore(Semaphore):