Mercurial > hg > cc > cirrus_home
view lib/python/lock.py @ 173:bc791ff523e7
x
author | Henry S. Thompson <ht@inf.ed.ac.uk> |
---|---|
date | Thu, 28 Jul 2022 17:25:09 +0100 |
parents | b6a5999d8e06 |
children |
line wrap: on
line source
# Courtesy of https://stackoverflow.com/a/46407326 import fcntl, os def lock_file(f): if f.writable(): fcntl.lockf(f, fcntl.LOCK_EX) def unlock_file(f): if f.writable(): fcntl.lockf(f, fcntl.LOCK_UN) # Class for ensuring that all file operations are atomic, treat # initialization like a standard call to 'open' that happens to be atomic. # This file opener *must* be used in a "with" block. class AtomicOpen: # Open the file with arguments provided by user. Then acquire # a lock on that file object (WARNING: Advisory locking). def __init__(self, path, *args, **kwargs): # Open the file and acquire a lock on the file before operating self.file = open(path,*args, **kwargs) # Lock the opened file lock_file(self.file) # Return the opened file object (knowing a lock has been obtained). def __enter__(self, *args, **kwargs): return self.file # Unlock the file and close the file object. def __exit__(self, exc_type=None, exc_value=None, traceback=None): # Flush to make sure all buffered contents are written to file. self.file.flush() os.fsync(self.file.fileno()) # Release the lock on the file. unlock_file(self.file) self.file.close() # Handle exceptions that may have come up during execution, by # default any exceptions are raised to the user. if (exc_type != None): return False else: return True