]> git.michaelhowe.org Git - packages/b/bup.git/commitdiff
Make CatPipe objects more resilient when interrupted.
authorAvery Pennarun <apenwarr@gmail.com>
Sat, 13 Feb 2010 23:21:09 +0000 (18:21 -0500)
committerAvery Pennarun <apenwarr@gmail.com>
Sat, 13 Feb 2010 23:22:25 +0000 (18:22 -0500)
If we stopped iterating halfway through a particular object, the iterator
wouldn't finishing reading all the data, which would mess up the state of
the git-cat-file pipe.  Now we read all the data even if we're going to just
throw it away.

git.py
helpers.py

diff --git a/git.py b/git.py
index 89b4c11a01ed7fd4d83e40678180c5fc5ce31820..dbd61c145c32cf9b264769ece47171863f91a135 100644 (file)
--- a/git.py
+++ b/git.py
@@ -617,11 +617,14 @@ class CatPipe:
                                       stdout=subprocess.PIPE,
                                       preexec_fn = _gitenv)
             self.get = self._fast_get
+            self.inprogress = 0
 
     def _fast_get(self, id):
+        assert(not self.inprogress)
         assert(id.find('\n') < 0)
         assert(id.find('\r') < 0)
         assert(id[0] != '-')
+        self.inprogress += 1
         self.p.stdin.write('%s\n' % id)
         hdr = self.p.stdout.readline()
         if hdr.endswith(' missing\n'):
@@ -630,15 +633,16 @@ class CatPipe:
         if len(spl) != 3 or len(spl[0]) != 40:
             raise GitError('expected blob, got %r' % spl)
         (hex, type, size) = spl
-        it = iter(chunkyreader(self.p.stdout, int(spl[2])))
-        try:
-            yield type
-            for blob in it:
-                yield blob
-        except StopIteration:
-            while 1:
-                it.next()
-        assert(self.p.stdout.readline() == '\n')
+
+        def ondone():
+            assert(self.p.stdout.readline() == '\n')
+            self.inprogress -= 1
+
+        it = AutoFlushIter(chunkyreader(self.p.stdout, int(spl[2])),
+                           ondone = ondone)
+        yield type
+        for blob in it:
+            yield blob
 
     def _slow_get(self, id):
         assert(id.find('\n') < 0)
@@ -674,8 +678,11 @@ class CatPipe:
                            % type)
 
     def join(self, id):
-        for d in self._join(self.get(id)):
-            yield d
+        try:
+            for d in self._join(self.get(id)):
+                yield d
+        except StopIteration:
+            log('booger!\n')
         
 
 def cat(id):
index 2bfdd536ec543357ba558ec2fef466e5ca46c6e7..2036ff4cc12a769b3a5d9ddbc73fd77f8a5e9532 100644 (file)
@@ -182,6 +182,24 @@ def chunkyreader(f, count = None):
             yield b
 
 
+class AutoFlushIter:
+    def __init__(self, it, ondone = None):
+        self.it = it
+        self.ondone = ondone
+
+    def __iter__(self):
+        return self
+        
+    def next(self):
+        return self.it.next()
+        
+    def __del__(self):
+        for i in self.it:
+            pass
+        if self.ondone:
+            self.ondone()
+
+
 def slashappend(s):
     if s and not s.endswith('/'):
         return s + '/'