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