| import os |
| import time |
| |
| |
| class FileBaton: |
| """A primitive, file-based synchronization utility.""" |
| |
| def __init__(self, lock_file_path, wait_seconds=0.1): |
| """ |
| Create a new :class:`FileBaton`. |
| |
| Args: |
| lock_file_path: The path to the file used for locking. |
| wait_seconds: The seconds to periodically sleep (spin) when |
| calling ``wait()``. |
| """ |
| self.lock_file_path = lock_file_path |
| self.wait_seconds = wait_seconds |
| self.fd = None |
| |
| def try_acquire(self): |
| """ |
| Try to atomically create a file under exclusive access. |
| |
| Returns: |
| True if the file could be created, else False. |
| """ |
| try: |
| self.fd = os.open(self.lock_file_path, os.O_CREAT | os.O_EXCL) |
| return True |
| except FileExistsError: |
| return False |
| |
| def wait(self): |
| """ |
| Periodically sleeps for a certain amount until the baton is released. |
| |
| The amount of time slept depends on the ``wait_seconds`` parameter |
| passed to the constructor. |
| """ |
| while os.path.exists(self.lock_file_path): |
| time.sleep(self.wait_seconds) |
| |
| def release(self): |
| """Release the baton and removes its file.""" |
| if self.fd is not None: |
| os.close(self.fd) |
| |
| os.remove(self.lock_file_path) |