@@ -356,8 +356,9 @@ def __repr__(self):
356
356
return f'<{ res [1 :- 1 ]} [{ extra } ]>'
357
357
358
358
def locked (self ):
359
- """Returns True if semaphore counter is zero."""
360
- return self ._value == 0
359
+ """Returns True if semaphore cannot be acquired immediately."""
360
+ return self ._value == 0 or (
361
+ any (not w .cancelled () for w in (self ._waiters or ())))
361
362
362
363
async def acquire (self ):
363
364
"""Acquire a semaphore.
@@ -368,8 +369,7 @@ async def acquire(self):
368
369
called release() to make it larger than 0, and then return
369
370
True.
370
371
"""
371
- if (not self .locked () and (self ._waiters is None or
372
- all (w .cancelled () for w in self ._waiters ))):
372
+ if not self .locked ():
373
373
self ._value -= 1
374
374
return True
375
375
@@ -387,13 +387,13 @@ async def acquire(self):
387
387
finally :
388
388
self ._waiters .remove (fut )
389
389
except exceptions .CancelledError :
390
- if not self .locked ():
391
- self ._wake_up_first ()
390
+ if not fut .cancelled ():
391
+ self ._value += 1
392
+ self ._wake_up_next ()
392
393
raise
393
394
394
- self ._value -= 1
395
- if not self .locked ():
396
- self ._wake_up_first ()
395
+ if self ._value > 0 :
396
+ self ._wake_up_next ()
397
397
return True
398
398
399
399
def release (self ):
@@ -403,22 +403,18 @@ def release(self):
403
403
become larger than zero again, wake up that coroutine.
404
404
"""
405
405
self ._value += 1
406
- self ._wake_up_first ()
406
+ self ._wake_up_next ()
407
407
408
- def _wake_up_first (self ):
409
- """Wake up the first waiter if it isn't done."""
408
+ def _wake_up_next (self ):
409
+ """Wake up the first waiter that isn't done."""
410
410
if not self ._waiters :
411
411
return
412
- try :
413
- fut = next (iter (self ._waiters ))
414
- except StopIteration :
415
- return
416
412
417
- # .done() necessarily means that a waiter will wake up later on and
418
- # either take the lock, or, if it was cancelled and lock wasn't
419
- # taken already, will hit this again and wake up a new waiter.
420
- if not fut .done ():
421
- fut . set_result ( True )
413
+ for fut in self . _waiters :
414
+ if not fut . done ():
415
+ self . _value -= 1
416
+ fut .set_result ( True )
417
+ return
422
418
423
419
424
420
class BoundedSemaphore (Semaphore ):
0 commit comments