Acquire a semaphore. If the internal counter is larger than zero on entry, decrement it by one and return True immediately. If it is zero on entry, block, waiting until some other task has called release() to make it larger than 0, and then return True.
(self)
| 384 | any(not w.cancelled() for w in (self._waiters or ()))) |
| 385 | |
| 386 | async def acquire(self): |
| 387 | """Acquire a semaphore. |
| 388 | |
| 389 | If the internal counter is larger than zero on entry, |
| 390 | decrement it by one and return True immediately. If it is |
| 391 | zero on entry, block, waiting until some other task has |
| 392 | called release() to make it larger than 0, and then return |
| 393 | True. |
| 394 | """ |
| 395 | if not self.locked(): |
| 396 | # Maintain FIFO, wait for others to start even if _value > 0. |
| 397 | self._value -= 1 |
| 398 | return True |
| 399 | |
| 400 | if self._waiters is None: |
| 401 | self._waiters = collections.deque() |
| 402 | fut = self._get_loop().create_future() |
| 403 | self._waiters.append(fut) |
| 404 | |
| 405 | try: |
| 406 | try: |
| 407 | await fut |
| 408 | finally: |
| 409 | self._waiters.remove(fut) |
| 410 | except exceptions.CancelledError: |
| 411 | # Currently the only exception designed be able to occur here. |
| 412 | if fut.done() and not fut.cancelled(): |
| 413 | # Our Future was successfully set to True via _wake_up_next(), |
| 414 | # but we are not about to successfully acquire(). Therefore we |
| 415 | # must undo the bookkeeping already done and attempt to wake |
| 416 | # up someone else. |
| 417 | self._value += 1 |
| 418 | raise |
| 419 | |
| 420 | finally: |
| 421 | # New waiters may have arrived but had to wait due to FIFO. |
| 422 | # Wake up as many as are allowed. |
| 423 | while self._value > 0: |
| 424 | if not self._wake_up_next(): |
| 425 | break # There was no-one to wake up. |
| 426 | return True |
| 427 | |
| 428 | def release(self): |
| 429 | """Release a semaphore, incrementing the internal counter by one. |