_locks_machinery.py 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import os
  2. import threading
  3. import weakref
  4. if not hasattr(os, "register_at_fork"):
  5. def create_logger_lock():
  6. return threading.Lock()
  7. def create_handler_lock():
  8. return threading.Lock()
  9. else:
  10. # While forking, we need to sanitize all locks to make sure the child process doesn't run into
  11. # a deadlock (if a lock already acquired is inherited) and to protect sink from corrupted state.
  12. # It's very important to acquire logger locks before handlers one to prevent possible deadlock
  13. # while 'remove()' is called for example.
  14. logger_locks = weakref.WeakSet()
  15. handler_locks = weakref.WeakSet()
  16. def acquire_locks():
  17. for lock in logger_locks:
  18. lock.acquire()
  19. for lock in handler_locks:
  20. lock.acquire()
  21. def release_locks():
  22. for lock in logger_locks:
  23. lock.release()
  24. for lock in handler_locks:
  25. lock.release()
  26. os.register_at_fork(
  27. before=acquire_locks,
  28. after_in_parent=release_locks,
  29. after_in_child=release_locks,
  30. )
  31. def create_logger_lock():
  32. lock = threading.Lock()
  33. logger_locks.add(lock)
  34. return lock
  35. def create_handler_lock():
  36. lock = threading.Lock()
  37. handler_locks.add(lock)
  38. return lock