@@ -357,8 +357,9 @@ def __repr__(self):
357
357
return f'<{ res [1 :- 1 ]} [{ extra } ]>'
358
358
359
359
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 ())))
362
363
363
364
async def acquire (self ):
364
365
"""Acquire a semaphore.
@@ -369,8 +370,7 @@ async def acquire(self):
369
370
called release() to make it larger than 0, and then return
370
371
True.
371
372
"""
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 ():
374
374
self ._value -= 1
375
375
return True
376
376
@@ -388,13 +388,13 @@ async def acquire(self):
388
388
finally :
389
389
self ._waiters .remove (fut )
390
390
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 ()
393
394
raise
394
395
395
- self ._value -= 1
396
- if not self .locked ():
397
- self ._wake_up_first ()
396
+ if self ._value > 0 :
397
+ self ._wake_up_next ()
398
398
return True
399
399
400
400
def release (self ):
@@ -404,22 +404,18 @@ def release(self):
404
404
become larger than zero again, wake up that coroutine.
405
405
"""
406
406
self ._value += 1
407
- self ._wake_up_first ()
407
+ self ._wake_up_next ()
408
408
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."""
411
411
if not self ._waiters :
412
412
return
413
- try :
414
- fut = next (iter (self ._waiters ))
415
- except StopIteration :
416
- return
417
413
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
423
419
424
420
425
421
class BoundedSemaphore (Semaphore ):
0 commit comments