fifo_lock.py 1020 B

12345678910111213141516171819202122232425262728293031323334353637
  1. import threading
  2. import collections
  3. # reference: https://gist.github.com/vitaliyp/6d54dd76ca2c3cdfc1149d33007dc34a
  4. class FIFOLock(object):
  5. def __init__(self):
  6. self._lock = threading.Lock()
  7. self._inner_lock = threading.Lock()
  8. self._pending_threads = collections.deque()
  9. def acquire(self, blocking=True):
  10. with self._inner_lock:
  11. lock_acquired = self._lock.acquire(False)
  12. if lock_acquired:
  13. return True
  14. elif not blocking:
  15. return False
  16. release_event = threading.Event()
  17. self._pending_threads.append(release_event)
  18. release_event.wait()
  19. return self._lock.acquire()
  20. def release(self):
  21. with self._inner_lock:
  22. if self._pending_threads:
  23. release_event = self._pending_threads.popleft()
  24. release_event.set()
  25. self._lock.release()
  26. __enter__ = acquire
  27. def __exit__(self, t, v, tb):
  28. self.release()