1 # -*- coding: utf-8 -*-
\r
2 # https://github.com/dmfrey/FileLock
\r
8 class FileLockException(Exception):
\r
12 """ A file locking mechanism that has context-manager support so
\r
13 you can use it in a with statement. This should be relatively cross
\r
14 compatible as it doesn't rely on msvcrt or fcntl for the locking.
\r
17 def __init__(self, file_name, timeout=10, delay=.05):
\r
18 """ Prepare the file locker. Specify the file to lock and optionally
\r
19 the maximum timeout and the delay between each attempt to lock.
\r
21 self.is_locked = False
\r
22 self.lockfile = os.path.join(os.getcwd(), "%s.lock" % file_name)
\r
23 self.file_name = file_name
\r
24 self.timeout = timeout
\r
29 """ Acquire the lock, if possible. If the lock is in use, it check again
\r
30 every `wait` seconds. It does this until it either gets the lock or
\r
31 exceeds `timeout` number of seconds, in which case it throws
\r
34 start_time = time.time()
\r
37 self.fd = os.open(self.lockfile, os.O_CREAT|os.O_EXCL|os.O_RDWR)
\r
39 except OSError as e:
\r
40 if e.errno != errno.EEXIST:
\r
42 if (time.time() - start_time) >= self.timeout:
\r
43 raise FileLockException("Timeout occured.")
\r
44 time.sleep(self.delay)
\r
45 self.is_locked = True
\r
49 """ Get rid of the lock by deleting the lockfile.
\r
50 When working in a `with` statement, this gets automatically
\r
55 os.unlink(self.lockfile)
\r
56 self.is_locked = False
\r
59 def __enter__(self):
\r
60 """ Activated when used in the with statement.
\r
61 Should automatically acquire a lock to be used in the with block.
\r
63 if not self.is_locked:
\r
68 def __exit__(self, type, value, traceback):
\r
69 """ Activated at the end of the with statement.
\r
70 It automatically releases the lock if it isn't locked.
\r
77 """ Make sure that the FileLock instance doesn't leave a lockfile
\r