@@ -357,8 +357,9 @@ def __repr__(self):
357357 return f'<{ res [1 :- 1 ]} [{ extra } ]>'
358358
359359 def locked (self ):
360- """Returns True if semaphore counter is zero."""
361- return self ._value == 0
360+ """Returns True if semaphore cannot be acquired immediately."""
361+ return self ._value == 0 or (
362+ any (not w .cancelled () for w in (self ._waiters or ())))
362363
363364 async def acquire (self ):
364365 """Acquire a semaphore.
@@ -369,8 +370,7 @@ async def acquire(self):
369370 called release() to make it larger than 0, and then return
370371 True.
371372 """
372- if (not self .locked () and (self ._waiters is None or
373- all (w .cancelled () for w in self ._waiters ))):
373+ if not self .locked ():
374374 self ._value -= 1
375375 return True
376376
@@ -388,13 +388,13 @@ async def acquire(self):
388388 finally :
389389 self ._waiters .remove (fut )
390390 except exceptions .CancelledError :
391- if not self .locked ():
392- self ._wake_up_first ()
391+ if not fut .cancelled ():
392+ self ._value += 1
393+ self ._wake_up_next ()
393394 raise
394395
395- self ._value -= 1
396- if not self .locked ():
397- self ._wake_up_first ()
396+ if self ._value > 0 :
397+ self ._wake_up_next ()
398398 return True
399399
400400 def release (self ):
@@ -404,22 +404,18 @@ def release(self):
404404 become larger than zero again, wake up that coroutine.
405405 """
406406 self ._value += 1
407- self ._wake_up_first ()
407+ self ._wake_up_next ()
408408
409- def _wake_up_first (self ):
410- """Wake up the first waiter if it isn't done."""
409+ def _wake_up_next (self ):
410+ """Wake up the first waiter that isn't done."""
411411 if not self ._waiters :
412412 return
413- try :
414- fut = next (iter (self ._waiters ))
415- except StopIteration :
416- return
417413
418- # .done() necessarily means that a waiter will wake up later on and
419- # either take the lock, or, if it was cancelled and lock wasn't
420- # taken already, will hit this again and wake up a new waiter.
421- if not fut .done ():
422- fut . set_result ( True )
414+ for fut in self . _waiters :
415+ if not fut . done ():
416+ self . _value -= 1
417+ fut .set_result ( True )
418+ return
423419
424420
425421class BoundedSemaphore (Semaphore ):
0 commit comments