diff options
Diffstat (limited to 'lib/bb/utils.py')
-rw-r--r-- | lib/bb/utils.py | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/lib/bb/utils.py b/lib/bb/utils.py index 857f5bcf9..607ffc506 100644 --- a/lib/bb/utils.py +++ b/lib/bb/utils.py @@ -31,6 +31,7 @@ import subprocess import glob import traceback import errno +import signal from commands import getstatusoutput from contextlib import contextmanager @@ -412,10 +413,30 @@ def fileslocked(files): for lock in locks: bb.utils.unlockfile(lock) -def lockfile(name, shared=False, retry=True): +@contextmanager +def timeout(seconds): + def timeout_handler(signum, frame): + pass + + original_handler = signal.signal(signal.SIGALRM, timeout_handler) + + try: + signal.alarm(seconds) + yield + finally: + signal.alarm(0) + signal.signal(signal.SIGALRM, original_handler) + +def lockfile(name, shared=False, retry=True, block=False): """ - Use the file fn as a lock file, return when the lock has been acquired. - Returns a variable to pass to unlockfile(). + Use the specified file as a lock file, return when the lock has + been acquired. Returns a variable to pass to unlockfile(). + Parameters: + retry: True to re-try locking if it fails, False otherwise + block: True to block until the lock succeeds, False otherwise + The retry and block parameters are kind of equivalent unless you + consider the possibility of sending a signal to the process to break + out - at which point you want block=True rather than retry=True. """ dirname = os.path.dirname(name) mkdirhier(dirname) @@ -428,7 +449,7 @@ def lockfile(name, shared=False, retry=True): op = fcntl.LOCK_EX if shared: op = fcntl.LOCK_SH - if not retry: + if not retry and not block: op = op | fcntl.LOCK_NB while True: |