summaryrefslogtreecommitdiff
path: root/lib/git
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2010-05-26 14:45:48 +0200
committerSebastian Thiel <byronimo@gmail.com>2010-05-26 14:45:48 +0200
commit17af1f64d5f1e62d40e11b75b1dd48e843748b49 (patch)
tree9ed97c5bf8b7c9a151122906bfe74789d39c5040 /lib/git
parent1019d4cf68d1acdbb4d6c1abb7e71ac9c0f581af (diff)
downloadgitpython-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
Diffstat (limited to 'lib/git')
-rw-r--r--lib/git/utils.py19
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)