diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2010-05-26 14:45:48 +0200 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2010-05-26 14:45:48 +0200 |
commit | 17af1f64d5f1e62d40e11b75b1dd48e843748b49 (patch) | |
tree | 9ed97c5bf8b7c9a151122906bfe74789d39c5040 | |
parent | 1019d4cf68d1acdbb4d6c1abb7e71ac9c0f581af (diff) | |
download | gitpython-17af1f64d5f1e62d40e11b75b1dd48e843748b49.tar.gz |
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
-rw-r--r-- | lib/git/utils.py | 19 |
1 files changed, 15 insertions, 4 deletions
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) |