From 17af1f64d5f1e62d40e11b75b1dd48e843748b49 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 26 May 2010 14:45:48 +0200 Subject: BlockingLockFile: added sanity check that raises IOError if the directory containing the lock was removed. This is unlikely to happen in a production envrironment, but may happen during testing, as folders are moved/deleted once the test is complete. Daemons might still be waiting for something, and they should be allowed to terminate instead of waiting for a possibly long time --- lib/git/utils.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'lib/git/utils.py') diff --git a/lib/git/utils.py b/lib/git/utils.py index 1fb58861..c21528b1 100644 --- a/lib/git/utils.py +++ b/lib/git/utils.py @@ -177,7 +177,11 @@ class LockFile(object): class BlockingLockFile(LockFile): """The lock file will block until a lock could be obtained, or fail after - a specified timeout""" + a specified timeout. + + :note: If the directory containing the lock was removed, an exception will + be raised during the blocking period, preventing hangs as the lock + can never be obtained.""" __slots__ = ("_check_interval", "_max_block_time") def __init__(self, file_path, check_interval_s=0.3, max_block_time_s=sys.maxint): """Configure the instance @@ -195,7 +199,7 @@ class BlockingLockFile(LockFile): def _obtain_lock(self): """This method blocks until it obtained the lock, or raises IOError if - it ran out of time. + it ran out of time or if the parent directory was not available anymore. If this method returns, you are guranteed to own the lock""" starttime = time.time() maxtime = starttime + float(self._max_block_time) @@ -203,9 +207,16 @@ class BlockingLockFile(LockFile): try: super(BlockingLockFile, self)._obtain_lock() except IOError: - curtime = time.time() + # synity check: if the directory leading to the lockfile is not + # readable anymore, raise an execption + curtime = time.time() + if not os.path.isdir(os.path.dirname(self._lock_file_path())): + msg = "Directory containing the lockfile %r was not readable anymore after waiting %g seconds" % (self._lock_file_path(), curtime - starttime) + raise IOError(msg) + # END handle missing directory + if curtime >= maxtime: - msg = "Waited %f seconds for lock at %r" % ( maxtime - starttime, self._lock_file_path()) + msg = "Waited %g seconds for lock at %r" % ( maxtime - starttime, self._lock_file_path()) raise IOError(msg) # END abort if we wait too long time.sleep(self._check_interval) -- cgit v1.2.1