Acquire a lock. This method blocks until the lock is unlocked, then sets it to locked and returns True.
(self)
| 88 | return self._locked |
| 89 | |
| 90 | async def acquire(self): |
| 91 | """Acquire a lock. |
| 92 | |
| 93 | This method blocks until the lock is unlocked, then sets it to |
| 94 | locked and returns True. |
| 95 | """ |
| 96 | # Implement fair scheduling, where thread always waits |
| 97 | # its turn. Jumping the queue if all are cancelled is an optimization. |
| 98 | if (not self._locked and (self._waiters is None or |
| 99 | all(w.cancelled() for w in self._waiters))): |
| 100 | self._locked = True |
| 101 | return True |
| 102 | |
| 103 | if self._waiters is None: |
| 104 | self._waiters = collections.deque() |
| 105 | fut = self._get_loop().create_future() |
| 106 | self._waiters.append(fut) |
| 107 | |
| 108 | try: |
| 109 | try: |
| 110 | await fut |
| 111 | finally: |
| 112 | self._waiters.remove(fut) |
| 113 | except exceptions.CancelledError: |
| 114 | # Currently the only exception designed be able to occur here. |
| 115 | |
| 116 | # Ensure the lock invariant: If lock is not claimed (or about |
| 117 | # to be claimed by us) and there is a Task in waiters, |
| 118 | # ensure that the Task at the head will run. |
| 119 | if not self._locked: |
| 120 | self._wake_up_first() |
| 121 | raise |
| 122 | |
| 123 | # assert self._locked is False |
| 124 | self._locked = True |
| 125 | return True |
| 126 | |
| 127 | def release(self): |
| 128 | """Release a lock. |