Decrement the counter. Returns an awaitable. Block if the counter is zero and wait for a `.release`. The awaitable raises `.TimeoutError` after the deadline.
(
self, timeout: Optional[Union[float, datetime.timedelta]] = None
)
| 414 | break |
| 415 | |
| 416 | def acquire( |
| 417 | self, timeout: Optional[Union[float, datetime.timedelta]] = None |
| 418 | ) -> Awaitable[_ReleasingContextManager]: |
| 419 | """Decrement the counter. Returns an awaitable. |
| 420 | |
| 421 | Block if the counter is zero and wait for a `.release`. The awaitable |
| 422 | raises `.TimeoutError` after the deadline. |
| 423 | """ |
| 424 | waiter = Future() # type: Future[_ReleasingContextManager] |
| 425 | if self._value > 0: |
| 426 | self._value -= 1 |
| 427 | waiter.set_result(_ReleasingContextManager(self)) |
| 428 | else: |
| 429 | self._waiters.append(waiter) |
| 430 | if timeout: |
| 431 | |
| 432 | def on_timeout() -> None: |
| 433 | if not waiter.done(): |
| 434 | waiter.set_exception(gen.TimeoutError()) |
| 435 | self._garbage_collect() |
| 436 | |
| 437 | io_loop = ioloop.IOLoop.current() |
| 438 | timeout_handle = io_loop.add_timeout(timeout, on_timeout) |
| 439 | waiter.add_done_callback( |
| 440 | lambda _: io_loop.remove_timeout(timeout_handle) |
| 441 | ) |
| 442 | return waiter |
| 443 | |
| 444 | def __enter__(self) -> None: |
| 445 | raise RuntimeError("Use 'async with' instead of 'with' for Semaphore") |